You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2016/02/13 07:33:55 UTC
[01/22] olingo-odata4 git commit: OLINGO-855: adding support for
odata-isolation header support acknowledgement to ServiceHandler interface
Repository: olingo-odata4
Updated Branches:
refs/heads/OLINGO-832_StreamSerializerPoC 5174f7089 -> 67494a789
OLINGO-855: adding support for odata-isolation header support acknowledgement to ServiceHandler interface
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/b317b900
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/b317b900
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/b317b900
Branch: refs/heads/OLINGO-832_StreamSerializerPoC
Commit: b317b9006d9a71c58a5b4a0f62558b11acba3dae
Parents: b9512ed
Author: Ramesh Reddy <ra...@jboss.org>
Authored: Mon Jan 25 09:20:54 2016 -0600
Committer: Ramesh Reddy <ra...@jboss.org>
Committed: Mon Jan 25 09:20:54 2016 -0600
----------------------------------------------------------------------
.../apache/olingo/commons/api/http/HttpHeader.java | 2 ++
.../apache/olingo/server/core/ServiceDispatcher.java | 9 +++++++++
.../org/apache/olingo/server/core/ServiceHandler.java | 14 ++++++++++++++
.../server/core/legacy/ProcessorServiceHandler.java | 5 +++++
.../apache/olingo/server/example/TripPinHandler.java | 5 +++++
.../olingo/server/example/TripPinServiceTest.java | 10 ++++++++++
6 files changed, 45 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b317b900/lib/commons-api/src/main/java/org/apache/olingo/commons/api/http/HttpHeader.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/http/HttpHeader.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/http/HttpHeader.java
index f33dbb0..91c65ca 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/http/HttpHeader.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/http/HttpHeader.java
@@ -176,4 +176,6 @@ public interface HttpHeader {
String ODATA_MAX_VERSION = "OData-MaxVersion";
/** Custom Header defined in the OData standard. */
String ODATA_ENTITY_ID = "OData-EntityID";
+ /** Custom Header defined in the OData standard. */
+ String ODATA_ISOLATION= "OData-Isolation";
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b317b900/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceDispatcher.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceDispatcher.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceDispatcher.java
index 45de757..cb718e1 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceDispatcher.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceDispatcher.java
@@ -24,6 +24,8 @@ import java.net.URISyntaxException;
import java.net.URL;
import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataRequest;
@@ -81,6 +83,13 @@ public class ServiceDispatcher extends RequestURLHierarchyVisitor {
new UriValidator().validate(uriInfo, odRequest.getMethod());
+ // part1, 8.2.6
+ String isolation = odRequest.getHeader(HttpHeader.ODATA_ISOLATION);
+ if (isolation != null && isolation.equals("snapshot") && !this.handler.supportsDataIsolation()) {
+ odResponse.setStatusCode(HttpStatusCode.PRECONDITION_FAILED.getStatusCode());
+ return;
+ }
+
visit(uriInfo);
// this should cover for any unsupported calls until they are implemented
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b317b900/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceHandler.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceHandler.java
index 68043de..ba96f94 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceHandler.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceHandler.java
@@ -282,4 +282,18 @@ public interface ServiceHandler extends Processor {
*/
void crossJoin(DataRequest dataRequest, List<String> entitySetNames, ODataResponse response)
throws ODataLibraryException, ODataApplicationException;
+
+ /**
+ * Snapshot isolation guarantees that all data returned for a request, including multiple requests within
+ * a batch or results retrieved across multiple pages, will be consistent as of a single point in time.
+ * Only data modifications made within the request (for example, by a data modification request
+ * within the same batch) are visible. The effect is as if the request generates a "snapshot" of
+ * the committed data as it existed at the start of the request. for more info see OData V4, Part1 8.2.6
+ *
+ * The contract for this interface is if it returns true, whenever the service deals with $skiptoken based
+ * results, they MUST be from same snapshot of the original request. false, the framework will automatically
+ * returns a 412.
+ * @return
+ */
+ boolean supportsDataIsolation();
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b317b900/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/legacy/ProcessorServiceHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/legacy/ProcessorServiceHandler.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/legacy/ProcessorServiceHandler.java
index b65f19c..db62c0a 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/legacy/ProcessorServiceHandler.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/legacy/ProcessorServiceHandler.java
@@ -437,4 +437,9 @@ public class ProcessorServiceHandler implements ServiceHandler {
throw new ODataHandlerException("not implemented",
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
}
+
+ @Override
+ public boolean supportsDataIsolation() {
+ return false;
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b317b900/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java
index db06558..fea02e9 100644
--- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java
@@ -556,4 +556,9 @@ public class TripPinHandler implements ServiceHandler {
updateEntity(request, entity, merge, entityETag, response);
}
}
+
+ @Override
+ public boolean supportsDataIsolation() {
+ return false;
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b317b900/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServiceTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServiceTest.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServiceTest.java
index ef5376d..3beb274 100644
--- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServiceTest.java
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServiceTest.java
@@ -42,6 +42,7 @@ import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
+import org.apache.olingo.commons.api.http.HttpHeader;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Ignore;
@@ -732,4 +733,13 @@ public class TripPinServiceTest {
HttpResponse response = httpGET(editUrl, 200);
EntityUtils.consumeQuietly(response.getEntity());
}
+
+ @Test
+ public void dataIsolation() throws Exception {
+ String url = baseURL + "/People";
+ HttpRequest request = new HttpGet(url);
+ request.setHeader(HttpHeader.ODATA_ISOLATION, "snapshot");
+ HttpResponse response = httpSend(request, 412);
+ EntityUtils.consumeQuietly(response.getEntity());
+ }
}
[17/22] olingo-odata4 git commit: OLINGO-874: Error handling
improvements
Posted by mi...@apache.org.
OLINGO-874: Error handling improvements
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/7a68ae68
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/7a68ae68
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/7a68ae68
Branch: refs/heads/OLINGO-832_StreamSerializerPoC
Commit: 7a68ae68ad72f13927814700be0debc3b481f008
Parents: b7005b7
Author: Ramesh Reddy <ra...@jboss.org>
Authored: Tue Feb 9 13:10:02 2016 -0600
Committer: Ramesh Reddy <ra...@jboss.org>
Committed: Tue Feb 9 14:44:02 2016 -0600
----------------------------------------------------------------------
.../apache/olingo/server/core/ErrorHandler.java | 47 ++++++----------
.../olingo/server/core/OData4HttpHandler.java | 10 ++--
.../olingo/server/core/ServiceDispatcher.java | 39 +++++++++++--
.../olingo/server/core/ServiceHandler.java | 13 ++++-
.../core/legacy/ProcessorServiceHandler.java | 7 +++
.../server/core/requests/BatchRequest.java | 11 +---
.../server/core/responses/EntityResponse.java | 1 +
.../core/responses/EntitySetResponse.java | 2 +
.../server/core/responses/ErrorResponse.java | 58 ++++++++++++++++++++
.../server/core/responses/MetadataResponse.java | 2 +
.../server/core/responses/PropertyResponse.java | 2 +
.../core/responses/ServiceDocumentResponse.java | 2 +
.../core/responses/ServiceResponseVisior.java | 4 ++
.../olingo/server/example/TripPinHandler.java | 9 ++-
14 files changed, 155 insertions(+), 52 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a68ae68/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ErrorHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ErrorHandler.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ErrorHandler.java
index 33f65cd..bfccc68 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ErrorHandler.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ErrorHandler.java
@@ -24,18 +24,16 @@ import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ODataServerError;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.deserializer.DeserializerException;
import org.apache.olingo.server.api.deserializer.batch.BatchDeserializerException;
-import org.apache.olingo.server.api.serializer.CustomContentTypeSupport;
import org.apache.olingo.server.api.serializer.ODataSerializer;
-import org.apache.olingo.server.api.serializer.RepresentationType;
import org.apache.olingo.server.api.serializer.SerializerException;
-import org.apache.olingo.server.api.uri.UriInfo;
-import org.apache.olingo.server.core.uri.parser.Parser;
+import org.apache.olingo.server.core.responses.ErrorResponse;
import org.apache.olingo.server.core.uri.parser.UriParserException;
import org.apache.olingo.server.core.uri.parser.UriParserSemanticException;
import org.apache.olingo.server.core.uri.parser.UriParserSyntaxException;
@@ -43,13 +41,16 @@ import org.apache.olingo.server.core.uri.validator.UriValidationException;
public class ErrorHandler {
private final OData odata;
+ private final ServiceHandler handler;
+ private final ContentType contentType;
private final ServiceMetadata metadata;
- private final CustomContentTypeSupport customContent;
-
- public ErrorHandler(OData odata, ServiceMetadata metadata, CustomContentTypeSupport customContent) {
+
+ public ErrorHandler(OData odata, ServiceMetadata metadata,
+ ServiceHandler handler, ContentType contentType) {
this.odata = odata;
+ this.handler = handler;
+ this.contentType = contentType;
this.metadata = metadata;
- this.customContent = customContent;
}
public void handleException(Exception e, ODataRequest request, ODataResponse response) {
@@ -80,7 +81,10 @@ public class ErrorHandler {
} else if(e instanceof ODataHandlerException) {
ODataServerError serverError = ODataExceptionHelper.createServerErrorObject((ODataHandlerException)e, null);
handleServerError(request, response, serverError);
- } else {
+ } else if(e instanceof ODataApplicationException) {
+ ODataServerError serverError = ODataExceptionHelper.createServerErrorObject((ODataApplicationException)e);
+ handleServerError(request, response, serverError);
+ }else {
ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e);
handleServerError(request, response, serverError);
}
@@ -88,29 +92,10 @@ public class ErrorHandler {
void handleServerError(final ODataRequest request, final ODataResponse response,
final ODataServerError serverError) {
- ContentType requestedContentType;
- try {
- final UriInfo uriInfo = new Parser(metadata.getEdm(), odata)
- .parseUri(request.getRawODataPath(), request.getRawQueryPath(), null);
- requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
- request, this.customContent, RepresentationType.ERROR);
- } catch (final ContentNegotiatorException e) {
- requestedContentType = ContentType.JSON;
- } catch (final UriParserException e) {
- requestedContentType = ContentType.JSON;
- } catch (final UriValidationException e) {
- requestedContentType = ContentType.JSON;
- }
- processError(response, serverError, requestedContentType);
- }
-
- void processError(ODataResponse response, ODataServerError serverError,
- ContentType requestedContentType) {
try {
- ODataSerializer serializer = this.odata.createSerializer(requestedContentType);
- response.setContent(serializer.error(serverError).getContent());
- response.setStatusCode(serverError.getStatusCode());
- response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
+ ODataSerializer serializer = this.odata.createSerializer(this.contentType);
+ ErrorResponse errorResponse = new ErrorResponse(this.metadata, serializer, this.contentType, response);
+ handler.processError(serverError, errorResponse);
} catch (Exception e) {
// This should never happen but to be sure we have this catch here
// to prevent sending a stacktrace to a client.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a68ae68/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/OData4HttpHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/OData4HttpHandler.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/OData4HttpHandler.java
index 7811cdf..18e1364 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/OData4HttpHandler.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/OData4HttpHandler.java
@@ -24,11 +24,12 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ODataLibraryException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
-import org.apache.olingo.server.api.ODataLibraryException;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.processor.Processor;
import org.apache.olingo.server.api.serializer.CustomContentTypeSupport;
@@ -63,12 +64,13 @@ public class OData4HttpHandler extends ODataHttpHandlerImpl {
ServiceDispatcher dispatcher = new ServiceDispatcher(this.odata, this.serviceMetadata,
handler, this.customContentTypeSupport);
dispatcher.execute(request, response);
-
+
} catch (Exception e) {
+ // also handle any unchecked exception thrown by service handler for proper serialization
ErrorHandler handler = new ErrorHandler(this.odata, this.serviceMetadata,
- this.customContentTypeSupport);
+ this.handler, ContentType.JSON);
handler.handleException(e, request, response);
- }
+ }
convertToHttp(httpResponse, response);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a68ae68/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceDispatcher.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceDispatcher.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceDispatcher.java
index cb718e1..fc5c88c 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceDispatcher.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceDispatcher.java
@@ -23,16 +23,18 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
+import org.apache.olingo.commons.api.ex.ODataException;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.ODataLibraryException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
-import org.apache.olingo.server.api.ODataLibraryException;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.serializer.CustomContentTypeSupport;
+import org.apache.olingo.server.api.serializer.RepresentationType;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.UriInfoBatch;
import org.apache.olingo.server.api.uri.UriInfoCrossjoin;
@@ -75,11 +77,36 @@ public class ServiceDispatcher extends RequestURLHierarchyVisitor {
this.customContentSupport = customContentSupport;
}
- public void execute(ODataRequest odRequest, ODataResponse odResponse)
- throws ODataLibraryException, ODataApplicationException {
-
- UriInfo uriInfo = new Parser(this.metadata.getEdm(), odata)
- .parseUri(odRequest.getRawODataPath(), odRequest.getRawQueryPath(), null);
+ public void execute(ODataRequest odRequest, ODataResponse odResponse) {
+ ContentType contentType = ContentType.JSON;
+ try {
+ contentType = ContentNegotiator.doContentNegotiation(null,
+ odRequest, this.customContentSupport, RepresentationType.ERROR);
+
+ UriInfo uriInfo = new Parser(this.metadata.getEdm(), odata)
+ .parseUri(odRequest.getRawODataPath(), odRequest.getRawQueryPath(), null);
+
+ contentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
+ odRequest, this.customContentSupport, RepresentationType.ERROR);
+
+ internalExecute(uriInfo, odRequest, odResponse);
+ } catch(ODataLibraryException e) {
+ handleException(e, contentType, odRequest, odResponse);
+ } catch(ODataApplicationException e) {
+ handleException(e, contentType, odRequest, odResponse);
+ }
+ }
+
+ protected void handleException(ODataException e, ContentType contentType,
+ ODataRequest odRequest, ODataResponse odResponse) {
+ ErrorHandler handler = new ErrorHandler(this.odata, this.metadata,
+ this.handler, contentType);
+ handler.handleException(e, odRequest, odResponse);
+ }
+
+ private void internalExecute(UriInfo uriInfo, ODataRequest odRequest,
+ ODataResponse odResponse) throws ODataLibraryException,
+ ODataApplicationException {
new UriValidator().validate(uriInfo, odRequest.getMethod());
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a68ae68/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceHandler.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceHandler.java
index ba96f94..8f8fc1d 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceHandler.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceHandler.java
@@ -26,9 +26,10 @@ import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.ODataLibraryException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
-import org.apache.olingo.server.api.ODataLibraryException;
+import org.apache.olingo.server.api.ODataServerError;
import org.apache.olingo.server.api.processor.Processor;
import org.apache.olingo.server.core.requests.ActionRequest;
import org.apache.olingo.server.core.requests.DataRequest;
@@ -37,6 +38,7 @@ import org.apache.olingo.server.core.requests.MediaRequest;
import org.apache.olingo.server.core.requests.MetadataRequest;
import org.apache.olingo.server.core.requests.ServiceDocumentRequest;
import org.apache.olingo.server.core.responses.EntityResponse;
+import org.apache.olingo.server.core.responses.ErrorResponse;
import org.apache.olingo.server.core.responses.MetadataResponse;
import org.apache.olingo.server.core.responses.NoContentResponse;
import org.apache.olingo.server.core.responses.PropertyResponse;
@@ -296,4 +298,13 @@ public interface ServiceHandler extends Processor {
* @return
*/
boolean supportsDataIsolation();
+
+
+ /**
+ * Handle errors generated by the framework as well as the service specific errors. This can be used
+ * one place handle error logging, error modification etc.
+ * @param error
+ * @param response
+ */
+ void processError(ODataServerError error, ErrorResponse response);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a68ae68/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/legacy/ProcessorServiceHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/legacy/ProcessorServiceHandler.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/legacy/ProcessorServiceHandler.java
index db62c0a..d4d0662 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/legacy/ProcessorServiceHandler.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/legacy/ProcessorServiceHandler.java
@@ -32,6 +32,7 @@ import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ODataLibraryException;
+import org.apache.olingo.server.api.ODataServerError;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.processor.ComplexCollectionProcessor;
import org.apache.olingo.server.api.processor.ComplexProcessor;
@@ -59,6 +60,7 @@ import org.apache.olingo.server.core.requests.ServiceDocumentRequest;
import org.apache.olingo.server.core.responses.CountResponse;
import org.apache.olingo.server.core.responses.EntityResponse;
import org.apache.olingo.server.core.responses.EntitySetResponse;
+import org.apache.olingo.server.core.responses.ErrorResponse;
import org.apache.olingo.server.core.responses.MetadataResponse;
import org.apache.olingo.server.core.responses.NoContentResponse;
import org.apache.olingo.server.core.responses.PrimitiveValueResponse;
@@ -442,4 +444,9 @@ public class ProcessorServiceHandler implements ServiceHandler {
public boolean supportsDataIsolation() {
return false;
}
+
+ @Override
+ public void processError(ODataServerError error, ErrorResponse response) {
+ response.writeError(error);
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a68ae68/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/BatchRequest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/BatchRequest.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/BatchRequest.java
index d14b5ad..2215594 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/BatchRequest.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/BatchRequest.java
@@ -29,16 +29,15 @@ import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.ODataLibraryException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
-import org.apache.olingo.server.api.ODataLibraryException;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.deserializer.batch.BatchDeserializerException;
import org.apache.olingo.server.api.deserializer.batch.BatchOptions;
import org.apache.olingo.server.api.deserializer.batch.BatchRequestPart;
import org.apache.olingo.server.api.deserializer.batch.ODataResponsePart;
import org.apache.olingo.server.core.ContentNegotiatorException;
-import org.apache.olingo.server.core.ErrorHandler;
import org.apache.olingo.server.core.ServiceDispatcher;
import org.apache.olingo.server.core.ServiceHandler;
import org.apache.olingo.server.core.ServiceRequest;
@@ -154,13 +153,7 @@ public class BatchRequest extends ServiceRequest {
ServiceDispatcher dispatcher = new ServiceDispatcher(this.odata, this.serviceMetadata, handler,
this.customContentType);
ODataResponse res = new ODataResponse();
- try {
- dispatcher.execute(singleRequest, res);
- } catch (Exception e) {
- ErrorHandler ehandler = new ErrorHandler(this.odata, this.serviceMetadata,
- getCustomContentTypeSupport());
- ehandler.handleException(e, singleRequest, res);
- }
+ dispatcher.execute(singleRequest, res);
return res;
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a68ae68/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/EntityResponse.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/EntityResponse.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/EntityResponse.java
index a0bbd14..5f54a24 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/EntityResponse.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/EntityResponse.java
@@ -162,6 +162,7 @@ public class EntityResponse extends ServiceResponse {
public void writeError(ODataServerError error) {
try {
+ writeHeader(HttpHeader.CONTENT_TYPE, this.responseContentType.getType());
writeContent(this.serializer.error(error).getContent(), error.getStatusCode(), true);
} catch (SerializerException e) {
writeServerError(true);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a68ae68/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/EntitySetResponse.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/EntitySetResponse.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/EntitySetResponse.java
index 0dd2bd8..09a48c1 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/EntitySetResponse.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/EntitySetResponse.java
@@ -24,6 +24,7 @@ import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ODataServerError;
@@ -84,6 +85,7 @@ public class EntitySetResponse extends ServiceResponse {
public void writeError(ODataServerError error) {
try {
+ writeHeader(HttpHeader.CONTENT_TYPE, this.responseContentType.getType());
writeContent(this.serializer.error(error).getContent(), error.getStatusCode(), true);
} catch (SerializerException e) {
writeServerError(true);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a68ae68/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ErrorResponse.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ErrorResponse.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ErrorResponse.java
new file mode 100644
index 0000000..2e1fbd6
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ErrorResponse.java
@@ -0,0 +1,58 @@
+/*
+ * 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.server.core.responses;
+
+import java.util.HashMap;
+
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.ODataLibraryException;
+import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.ODataServerError;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.serializer.ODataSerializer;
+import org.apache.olingo.server.api.serializer.SerializerException;
+
+public class ErrorResponse extends ServiceResponse {
+ private ContentType contentType;
+ private ODataSerializer serializer;
+
+ public ErrorResponse(ServiceMetadata metadata, ODataSerializer serializer,
+ ContentType contentType, ODataResponse response) {
+ super(metadata, response, new HashMap<String, String>());
+ this.contentType = contentType;
+ this.serializer = serializer;
+ }
+
+ @Override
+ public void accepts(ServiceResponseVisior visitor)
+ throws ODataLibraryException, ODataApplicationException {
+ visitor.visit(this);
+ }
+
+ public void writeError(ODataServerError error) {
+ try {
+ writeHeader(HttpHeader.CONTENT_TYPE, this.contentType.getType());
+ writeContent(this.serializer.error(error).getContent(), error.getStatusCode(), true);
+ } catch (SerializerException e) {
+ writeServerError(true);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a68ae68/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/MetadataResponse.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/MetadataResponse.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/MetadataResponse.java
index 5facd96..c030336 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/MetadataResponse.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/MetadataResponse.java
@@ -21,6 +21,7 @@ package org.apache.olingo.server.core.responses;
import java.util.Map;
import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ODataServerError;
@@ -63,6 +64,7 @@ public class MetadataResponse extends ServiceResponse {
public void writeError(ODataServerError error) {
try {
+ writeHeader(HttpHeader.CONTENT_TYPE, this.responseContentType.getType());
writeContent(this.serializer.error(error).getContent(), error.getStatusCode(), true);
} catch (SerializerException e) {
writeServerError(true);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a68ae68/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/PropertyResponse.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/PropertyResponse.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/PropertyResponse.java
index 1fc5416..f9c35ba 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/PropertyResponse.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/PropertyResponse.java
@@ -27,6 +27,7 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataResponse;
@@ -148,6 +149,7 @@ public class PropertyResponse extends ServiceResponse {
public void writeError(ODataServerError error) {
try {
+ writeHeader(HttpHeader.CONTENT_TYPE, this.responseContentType.getType());
writeContent(this.serializer.error(error).getContent(), error.getStatusCode(), true);
} catch (SerializerException e) {
writeServerError(true);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a68ae68/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceDocumentResponse.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceDocumentResponse.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceDocumentResponse.java
index 0d7a88c..a4192e7 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceDocumentResponse.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceDocumentResponse.java
@@ -21,6 +21,7 @@ package org.apache.olingo.server.core.responses;
import java.util.Map;
import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ODataServerError;
@@ -64,6 +65,7 @@ public class ServiceDocumentResponse extends ServiceResponse {
public void writeError(ODataServerError error) {
try {
+ writeHeader(HttpHeader.CONTENT_TYPE, this.responseContentType.getType());
writeContent(this.serializer.error(error).getContent(), error.getStatusCode(), true);
} catch (SerializerException e) {
writeServerError(true);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a68ae68/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceResponseVisior.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceResponseVisior.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceResponseVisior.java
index 5be8113..fb73b8c 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceResponseVisior.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceResponseVisior.java
@@ -67,4 +67,8 @@ public class ServiceResponseVisior {
ODataApplicationException {
response.writeServerError(true);
}
+
+ public void visit(ErrorResponse response) {
+ response.writeServerError(true);
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a68ae68/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java
index fea02e9..4d2dbb9 100644
--- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java
@@ -40,9 +40,10 @@ import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.ODataLibraryException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
-import org.apache.olingo.server.api.ODataLibraryException;
+import org.apache.olingo.server.api.ODataServerError;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.uri.UriParameter;
import org.apache.olingo.server.api.uri.UriResourceNavigation;
@@ -56,6 +57,7 @@ import org.apache.olingo.server.core.requests.ServiceDocumentRequest;
import org.apache.olingo.server.core.responses.CountResponse;
import org.apache.olingo.server.core.responses.EntityResponse;
import org.apache.olingo.server.core.responses.EntitySetResponse;
+import org.apache.olingo.server.core.responses.ErrorResponse;
import org.apache.olingo.server.core.responses.MetadataResponse;
import org.apache.olingo.server.core.responses.NoContentResponse;
import org.apache.olingo.server.core.responses.PrimitiveValueResponse;
@@ -561,4 +563,9 @@ public class TripPinHandler implements ServiceHandler {
public boolean supportsDataIsolation() {
return false;
}
+
+ @Override
+ public void processError(ODataServerError error, ErrorResponse response) {
+ response.writeError(error);
+ }
}
[14/22] olingo-odata4 git commit: Merge branch 'master' of
https://git-wip-us.apache.org/repos/asf/olingo-odata4
Posted by mi...@apache.org.
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/olingo-odata4
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/280bc019
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/280bc019
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/280bc019
Branch: refs/heads/OLINGO-832_StreamSerializerPoC
Commit: 280bc019cebd8d05f7f27ecd2b069e3eb5300a69
Parents: 6d94f0e 53065cd
Author: Ramesh Reddy <ra...@jboss.org>
Authored: Sat Feb 6 13:32:04 2016 -0600
Committer: Ramesh Reddy <ra...@jboss.org>
Committed: Sat Feb 6 13:32:04 2016 -0600
----------------------------------------------------------------------
.../commons/AbstractInvocationHandler.java | 17 +-
.../AbstractStructuredInvocationHandler.java | 2 +-
.../commons/AnnotatationsInvocationHandler.java | 2 +-
.../ComplexCollectionInvocationHandler.java | 2 +-
.../proxy/commons/ComplexInvocationHandler.java | 6 +-
.../proxy/commons/EdmStreamValueHandler.java | 2 +-
.../EntityCollectionInvocationHandler.java | 2 +-
.../EntityContainerInvocationHandler.java | 4 +-
.../proxy/commons/EntityInvocationHandler.java | 6 +-
.../commons/EntitySetInvocationHandler.java | 2 +-
.../proxy/commons/InvokerInvocationHandler.java | 2 +-
.../commons/OperationInvocationHandler.java | 2 +-
.../PrimitiveCollectionInvocationHandler.java | 2 +-
...turedComposableInvokerInvocationHandler.java | 2 +-
.../olingo/ext/proxy/utils/CoreUtils.java | 5 +-
.../org/apache/olingo/fit/AbstractServices.java | 1947 --------------
.../main/java/org/apache/olingo/fit/Demo.java | 6 +-
.../java/org/apache/olingo/fit/OpenType.java | 5 +-
.../java/org/apache/olingo/fit/Services.java | 2511 +++++++++++++++---
.../org/apache/olingo/fit/Vocabularies.java | 10 +-
.../apache/olingo/fit/metadata/EntitySet.java | 8 -
.../olingo/fit/rest/OAuth2RequestFilter.java | 3 +-
.../fit/serializer/FITAtomDeserializer.java | 13 +-
.../olingo/fit/utils/AbstractUtilities.java | 22 +-
.../org/apache/olingo/fit/utils/Accept.java | 31 +-
.../org/apache/olingo/fit/utils/Commons.java | 24 +-
.../apache/olingo/fit/utils/ConstantKey.java | 10 +-
.../org/apache/olingo/fit/utils/Constants.java | 7 -
.../org/apache/olingo/fit/utils/FSManager.java | 25 +-
.../fit/utils/InjectableSerializerProvider.java | 42 -
.../apache/olingo/fit/utils/JSONUtilities.java | 14 +-
.../olingo/fit/utils/MetadataLinkInfo.java | 182 --
.../apache/olingo/fit/utils/XMLUtilities.java | 3 +
.../proxy/demo/odatademo/types/Customer.java | 6 +-
.../proxy/demo/odatademo/types/Employee.java | 6 +-
.../demo/odatademo/types/FeaturedProduct.java | 6 +-
.../opentypesservice/types/IndexedRow.java | 8 +-
.../odatawcfservice/types/CreditCardPI.java | 6 +-
.../odatawcfservice/types/Customer.java | 6 +-
.../odatawcfservice/types/Employee.java | 6 +-
.../odatawcfservice/types/PublicCompany.java | 8 +-
.../tecsvc/client/EntityReferencesITCase.java | 13 +-
.../ExpandWithSystemQueryOptionsITCase.java | 74 +-
.../core/domain/AbstractClientEntitySet.java | 114 -
.../core/domain/ClientCollectionValueImpl.java | 2 +-
.../client/core/domain/ClientEntitySetImpl.java | 74 +-
.../core/domain/ClientPrimitiveValueImpl.java | 5 +-
.../client/core/domain/ClientPropertyImpl.java | 135 +-
.../client/core/domain/ClientValuableImpl.java | 22 +-
.../core/serialization/ODataBinderImpl.java | 2 +-
.../apache/olingo/client/core/AbstractTest.java | 9 +-
.../org/apache/olingo/client/core/AtomTest.java | 6 -
.../olingo/client/core/EntitySetTest.java | 22 +-
.../apache/olingo/client/core/EntityTest.java | 73 +-
.../apache/olingo/client/core/ErrorTest.java | 8 +-
.../org/apache/olingo/client/core/JSONTest.java | 46 +-
.../apache/olingo/client/core/MetadataTest.java | 33 +-
.../olingo/client/core/PrimitiveValueTest.java | 22 +-
.../apache/olingo/client/core/PropertyTest.java | 38 +-
.../olingo/client/core/ServiceDocumentTest.java | 16 +-
.../client/core/uri/FilterFactoryTest.java | 8 +-
.../olingo/client/core/uri/URIBuilderTest.java | 71 +-
.../olingo/commons/api/edm/geo/Geospatial.java | 7 +-
.../commons/core/edm/EdmEntityTypeImpl.java | 7 +-
.../core/edm/EdmNavigationPropertyImpl.java | 3 +-
.../commons/core/edm/EdmParameterImpl.java | 3 +-
.../commons/core/edm/EdmPropertyImpl.java | 5 +-
.../edm/provider/EdmEntityTypeImplTest.java | 19 +
.../uri/queryoption/SystemQueryOptionKind.java | 22 +-
.../apache/olingo/server/core/ODataHandler.java | 4 +-
.../server/core/ODataHttpHandlerImpl.java | 19 +-
.../core/batchhandler/BatchFacadeImpl.java | 18 +-
.../server/core/batchhandler/BatchHandler.java | 2 +-
.../olingo/server/core/uri/UriInfoImpl.java | 37 +-
.../server/core/uri/parser/ExpandParser.java | 30 +-
.../core/uri/parser/ExpressionParser.java | 85 +-
.../server/core/uri/parser/FilterParser.java | 6 +-
.../server/core/uri/parser/OrderByParser.java | 6 +-
.../olingo/server/core/uri/parser/Parser.java | 354 +--
.../server/core/uri/parser/ParserHelper.java | 168 +-
.../core/uri/parser/ResourcePathParser.java | 38 +-
.../server/core/uri/parser/SelectParser.java | 12 +-
.../server/core/uri/parser/UriTokenizer.java | 12 +-
.../uri/queryoption/expression/AliasImpl.java | 9 +-
.../uri/validator/UriValidationException.java | 4 +-
.../server/core/uri/validator/UriValidator.java | 513 +---
.../server-core-exceptions-i18n.properties | 1 +
.../olingo/server/core/uri/UriInfoImplTest.java | 50 +-
.../core/uri/parser/ExpressionParserTest.java | 2 +-
.../core/uri/parser/UriTokenizerTest.java | 3 +
.../olingo/server/tecsvc/data/DataProvider.java | 12 +-
.../SystemQueryOptionsRuntimeException.java | 3 +-
.../tecsvc/provider/ContainerProvider.java | 6 +-
.../core/uri/parser/TestFullResourcePath.java | 112 +-
.../core/uri/queryoption/QueryOptionTest.java | 4 +-
.../queryoption/expression/ExpressionTest.java | 6 +-
.../core/uri/testutil/FilterValidator.java | 51 +-
.../core/uri/validator/UriValidatorTest.java | 68 +-
98 files changed, 3310 insertions(+), 4157 deletions(-)
----------------------------------------------------------------------
[06/22] olingo-odata4 git commit: [OLINGO-852] less warnings +
general clean-up
Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/test/java/org/apache/olingo/client/core/EntityTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/EntityTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/EntityTest.java
index 9f5d405..0d075a9 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/EntityTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/EntityTest.java
@@ -50,11 +50,6 @@ import org.junit.Test;
public class EntityTest extends AbstractTest {
- @Override
- protected ODataClient getClient() {
- return v4Client;
- }
-
private EdmEnabledODataClient getEdmEnabledClient() {
return new EdmEnabledODataClientImpl(null, null, null) {
@@ -78,8 +73,8 @@ public class EntityTest extends AbstractTest {
private void singleton(final ContentType contentType) throws Exception {
final InputStream input = getClass().getResourceAsStream("VipCustomer." + getSuffix(contentType));
- final ClientEntity entity = getClient().getBinder().getODataEntity(
- getClient().getDeserializer(contentType).toEntity(input));
+ final ClientEntity entity = client.getBinder().getODataEntity(
+ client.getDeserializer(contentType).toEntity(input));
assertNotNull(entity);
assertEquals("Microsoft.Test.OData.Services.ODataWCFService.Customer", entity.getTypeName().toString());
@@ -120,8 +115,8 @@ public class EntityTest extends AbstractTest {
// operations won't get serialized
entity.getOperations().clear();
- final ClientEntity written = getClient().getBinder().getODataEntity(
- new ResWrap<Entity>((URI) null, null, getClient().getBinder().getEntity(entity)));
+ final ClientEntity written = client.getBinder().getODataEntity(
+ new ResWrap<Entity>((URI) null, null, client.getBinder().getEntity(entity)));
assertEquals(entity, written);
input.close();
}
@@ -138,8 +133,8 @@ public class EntityTest extends AbstractTest {
private void withEnums(final ContentType contentType) throws Exception {
final InputStream input = getClass().getResourceAsStream("Products_5." + getSuffix(contentType));
- final ClientEntity entity = getClient().getBinder().getODataEntity(
- getClient().getDeserializer(contentType).toEntity(input));
+ final ClientEntity entity = client.getBinder().getODataEntity(
+ client.getDeserializer(contentType).toEntity(input));
assertNotNull(entity);
final ClientProperty skinColor = entity.getProperty("SkinColor");
@@ -156,8 +151,8 @@ public class EntityTest extends AbstractTest {
// operations won't get serialized
entity.getOperations().clear();
- final ClientEntity written = getClient().getBinder().getODataEntity(
- new ResWrap<Entity>((URI) null, null, getClient().getBinder().getEntity(entity)));
+ final ClientEntity written = client.getBinder().getODataEntity(
+ new ResWrap<Entity>((URI) null, null, client.getBinder().getEntity(entity)));
assertEquals(entity, written);
input.close();
}
@@ -175,8 +170,8 @@ public class EntityTest extends AbstractTest {
private void withInlineEntitySet(final ContentType contentType) throws Exception {
final InputStream input = getClass().getResourceAsStream(
"Accounts_101_expand_MyPaymentInstruments." + getSuffix(contentType));
- final ClientEntity entity = getClient().getBinder().getODataEntity(
- getClient().getDeserializer(contentType).toEntity(input));
+ final ClientEntity entity = client.getBinder().getODataEntity(
+ client.getDeserializer(contentType).toEntity(input));
assertNotNull(entity);
final ClientLink instruments = entity.getNavigationLink("MyPaymentInstruments");
@@ -191,8 +186,8 @@ public class EntityTest extends AbstractTest {
inline.getEntitySet().setCount(3);
// operations won't get serialized
entity.getOperations().clear();
- final ClientEntity written = getClient().getBinder().getODataEntity(
- new ResWrap<Entity>((URI) null, null, getClient().getBinder().getEntity(entity)));
+ final ClientEntity written = client.getBinder().getODataEntity(
+ new ResWrap<Entity>((URI) null, null, client.getBinder().getEntity(entity)));
assertEquals(entity, written);
input.close();
}
@@ -210,16 +205,16 @@ public class EntityTest extends AbstractTest {
private void mediaEntity(final ContentType contentType) throws Exception {
final InputStream input = getClass().getResourceAsStream(
"Advertisements_f89dee73-af9f-4cd4-b330-db93c25ff3c7." + getSuffix(contentType));
- final ClientEntity entity = getClient().getBinder().getODataEntity(
- getClient().getDeserializer(contentType).toEntity(input));
+ final ClientEntity entity = client.getBinder().getODataEntity(
+ client.getDeserializer(contentType).toEntity(input));
assertNotNull(entity);
assertTrue(entity.isMediaEntity());
assertNotNull(entity.getMediaContentSource());
assertEquals("\"8zOOKKvgOtptr4gt8IrnapX3jds=\"", entity.getMediaETag());
- final ClientEntity written = getClient().getBinder().getODataEntity(
- new ResWrap<Entity>((URI) null, null, getClient().getBinder().getEntity(entity)));
+ final ClientEntity written = client.getBinder().getODataEntity(
+ new ResWrap<Entity>((URI) null, null, client.getBinder().getEntity(entity)));
assertEquals(entity, written);
input.close();
}
@@ -236,8 +231,8 @@ public class EntityTest extends AbstractTest {
private void withStream(final ContentType contentType) throws Exception {
final InputStream input = getClass().getResourceAsStream("PersonDetails_1." + getSuffix(contentType));
- final ClientEntity entity = getClient().getBinder().getODataEntity(
- getClient().getDeserializer(contentType).toEntity(input));
+ final ClientEntity entity = client.getBinder().getODataEntity(
+ client.getDeserializer(contentType).toEntity(input));
assertNotNull(entity);
assertFalse(entity.isMediaEntity());
@@ -245,8 +240,8 @@ public class EntityTest extends AbstractTest {
final ClientLink editMedia = entity.getMediaEditLink("Photo");
assertNotNull(editMedia);
- final ClientEntity written = getClient().getBinder().getODataEntity(
- new ResWrap<Entity>((URI) null, null, getClient().getBinder().getEntity(entity)));
+ final ClientEntity written = client.getBinder().getODataEntity(
+ new ResWrap<Entity>((URI) null, null, client.getBinder().getEntity(entity)));
assertEquals(entity, written);
input.close();
}
@@ -263,14 +258,14 @@ public class EntityTest extends AbstractTest {
private void ref(final ContentType contentType) throws Exception {
final InputStream input = getClass().getResourceAsStream("entityReference." + getSuffix(contentType));
- final ClientEntity entity = getClient().getBinder().getODataEntity(
- getClient().getDeserializer(contentType).toEntity(input));
+ final ClientEntity entity = client.getBinder().getODataEntity(
+ client.getDeserializer(contentType).toEntity(input));
assertNotNull(entity);
assertNotNull(entity.getId());
- final ClientEntity written = getClient().getBinder().getODataEntity(
- new ResWrap<Entity>((URI) null, null, getClient().getBinder().getEntity(entity)));
+ final ClientEntity written = client.getBinder().getODataEntity(
+ new ResWrap<Entity>((URI) null, null, client.getBinder().getEntity(entity)));
assertEquals(entity, written);
input.close();
}
@@ -287,8 +282,8 @@ public class EntityTest extends AbstractTest {
private void complexNavigationProperties(final ContentType contentType) throws Exception {
final InputStream input = getClass().getResourceAsStream("entity.withcomplexnavigation." + getSuffix(contentType));
- final ClientEntity entity = getClient().getBinder().getODataEntity(
- getClient().getDeserializer(contentType).toEntity(input));
+ final ClientEntity entity = client.getBinder().getODataEntity(
+ client.getDeserializer(contentType).toEntity(input));
assertNotNull(entity);
final ClientComplexValue addressValue = entity.getProperty("Address").getComplexValue();
@@ -297,8 +292,8 @@ public class EntityTest extends AbstractTest {
// ETag is not serialized
entity.setETag(null);
- final ClientEntity written = getClient().getBinder().getODataEntity(
- new ResWrap<Entity>((URI) null, null, getClient().getBinder().getEntity(entity)));
+ final ClientEntity written = client.getBinder().getODataEntity(
+ new ResWrap<Entity>((URI) null, null, client.getBinder().getEntity(entity)));
assertEquals(entity, written);
input.close();
}
@@ -315,8 +310,8 @@ public class EntityTest extends AbstractTest {
private void annotated(final ContentType contentType) throws EdmPrimitiveTypeException, Exception {
final InputStream input = getClass().getResourceAsStream("annotated." + getSuffix(contentType));
- final ClientEntity entity = getClient().getBinder().getODataEntity(
- getClient().getDeserializer(contentType).toEntity(input));
+ final ClientEntity entity = client.getBinder().getODataEntity(
+ client.getDeserializer(contentType).toEntity(input));
assertNotNull(entity);
assertFalse(entity.getAnnotations().isEmpty());
@@ -343,8 +338,8 @@ public class EntityTest extends AbstractTest {
assertEquals(2,
annotation.getValue().asComplex().get("order").getPrimitiveValue().toCastValue(Integer.class), 0);
- final ClientEntity written = getClient().getBinder().getODataEntity(
- new ResWrap<Entity>((URI) null, null, getClient().getBinder().getEntity(entity)));
+ final ClientEntity written = client.getBinder().getODataEntity(
+ new ResWrap<Entity>((URI) null, null, client.getBinder().getEntity(entity)));
assertEquals(entity, written);
input.close();
}
@@ -374,7 +369,7 @@ public class EntityTest extends AbstractTest {
@Test
public void derivedFromAtom() throws Exception {
- derived(getClient(), ContentType.APPLICATION_ATOM_XML);
+ derived(client, ContentType.APPLICATION_ATOM_XML);
}
@Test
@@ -384,6 +379,6 @@ public class EntityTest extends AbstractTest {
@Test
public void derivedFromFullJSON() throws Exception {
- derived(getClient(), ContentType.JSON_FULL_METADATA);
+ derived(client, ContentType.JSON_FULL_METADATA);
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/test/java/org/apache/olingo/client/core/ErrorTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/ErrorTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/ErrorTest.java
index 8ced6a3..60bbcd0 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/ErrorTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/ErrorTest.java
@@ -21,7 +21,6 @@ package org.apache.olingo.client.core;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-import org.apache.olingo.client.api.ODataClient;
import org.apache.olingo.client.api.serialization.ODataDeserializerException;
import org.apache.olingo.commons.api.ex.ODataError;
import org.apache.olingo.commons.api.format.ContentType;
@@ -29,13 +28,8 @@ import org.junit.Test;
public class ErrorTest extends AbstractTest {
- @Override
- protected ODataClient getClient() {
- return v4Client;
- }
-
private ODataError error(final String name, final ContentType contentType) throws ODataDeserializerException {
- final ODataError error = getClient().getDeserializer(contentType).toError(
+ final ODataError error = client.getDeserializer(contentType).toError(
getClass().getResourceAsStream(name + "." + getSuffix(contentType)));
assertNotNull(error);
return error;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/test/java/org/apache/olingo/client/core/JSONTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/JSONTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/JSONTest.java
index 9273229..a276c4f 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/JSONTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/JSONTest.java
@@ -30,7 +30,6 @@ import java.util.List;
import java.util.Map;
import org.apache.commons.io.IOUtils;
-import org.apache.olingo.client.api.ODataClient;
import org.apache.olingo.client.api.domain.ClientCollectionValue;
import org.apache.olingo.client.api.domain.ClientComplexValue;
import org.apache.olingo.client.api.domain.ClientEntity;
@@ -50,11 +49,6 @@ public class JSONTest extends AbstractTest {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
- @Override
- protected ODataClient getClient() {
- return v4Client;
- }
-
protected ContentType getODataPubFormat() {
return ContentType.JSON;
}
@@ -129,7 +123,7 @@ public class JSONTest extends AbstractTest {
protected void entitySet(final String filename, final ContentType contentType) throws Exception {
final StringWriter writer = new StringWriter();
- getClient().getSerializer(contentType).write(writer, getClient().getDeserializer(contentType).toEntitySet(
+ client.getSerializer(contentType).write(writer, client.getDeserializer(contentType).toEntitySet(
getClass().getResourceAsStream(filename + "." + getSuffix(contentType))).getPayload());
assertSimilar(filename + "." + getSuffix(contentType), writer.toString());
@@ -143,7 +137,7 @@ public class JSONTest extends AbstractTest {
protected void entity(final String filename, final ContentType contentType) throws Exception {
final StringWriter writer = new StringWriter();
- getClient().getSerializer(contentType).write(writer, getClient().getDeserializer(contentType).toEntity(
+ client.getSerializer(contentType).write(writer, client.getDeserializer(contentType).toEntity(
getClass().getResourceAsStream(filename + "." + getSuffix(contentType))).getPayload());
assertSimilar(filename + "." + getSuffix(contentType), writer.toString());
}
@@ -169,7 +163,7 @@ public class JSONTest extends AbstractTest {
protected void property(final String filename, final ContentType contentType) throws Exception {
final StringWriter writer = new StringWriter();
- getClient().getSerializer(contentType).write(writer, getClient().getDeserializer(contentType).
+ client.getSerializer(contentType).write(writer, client.getDeserializer(contentType).
toProperty(getClass().getResourceAsStream(filename + "." + getSuffix(contentType))).getPayload());
assertSimilar(filename + "." + getSuffix(contentType), writer.toString());
@@ -185,12 +179,12 @@ public class JSONTest extends AbstractTest {
@Test
public void crossjoin() throws Exception {
- assertNotNull(getClient().getDeserializer(ContentType.JSON_FULL_METADATA).toEntitySet(
+ assertNotNull(client.getDeserializer(ContentType.JSON_FULL_METADATA).toEntitySet(
getClass().getResourceAsStream("crossjoin.json")));
}
protected void delta(final String filename, final ContentType contentType) throws Exception {
- final Delta delta = getClient().getDeserializer(contentType).toDelta(
+ final Delta delta = client.getDeserializer(contentType).toDelta(
getClass().getResourceAsStream(filename + "." + getSuffix(contentType))).getPayload();
assertNotNull(delta);
assertNotNull(delta.getDeltaLink());
@@ -223,30 +217,30 @@ public class JSONTest extends AbstractTest {
@Test
public void issueOLINGO390() throws Exception {
- final ClientEntity message = getClient().getObjectFactory().
+ final ClientEntity message = client.getObjectFactory().
newEntity(new FullQualifiedName("Microsoft.Exchange.Services.OData.Model.Message"));
- final ClientComplexValue toRecipient = getClient().getObjectFactory().
+ final ClientComplexValue toRecipient = client.getObjectFactory().
newComplexValue("Microsoft.Exchange.Services.OData.Model.Recipient");
- toRecipient.add(getClient().getObjectFactory().newPrimitiveProperty("Name",
- getClient().getObjectFactory().newPrimitiveValueBuilder().buildString("challen_olingo_client")));
- toRecipient.add(getClient().getObjectFactory().newPrimitiveProperty("Address",
- getClient().getObjectFactory().newPrimitiveValueBuilder().buildString("challenh@microsoft.com")));
- final ClientCollectionValue<ClientValue> toRecipients = getClient().getObjectFactory().
+ toRecipient.add(client.getObjectFactory().newPrimitiveProperty("Name",
+ client.getObjectFactory().newPrimitiveValueBuilder().buildString("challen_olingo_client")));
+ toRecipient.add(client.getObjectFactory().newPrimitiveProperty("Address",
+ client.getObjectFactory().newPrimitiveValueBuilder().buildString("challenh@microsoft.com")));
+ final ClientCollectionValue<ClientValue> toRecipients = client.getObjectFactory().
newCollectionValue("Microsoft.Exchange.Services.OData.Model.Recipient");
toRecipients.add(toRecipient);
- message.getProperties().add(getClient().getObjectFactory().newCollectionProperty("ToRecipients", toRecipients));
+ message.getProperties().add(client.getObjectFactory().newCollectionProperty("ToRecipients", toRecipients));
final ClientComplexValue body =
- getClient().getObjectFactory().newComplexValue("Microsoft.Exchange.Services.OData.Model.ItemBody");
- body.add(getClient().getObjectFactory().newPrimitiveProperty("Content",
- getClient().getObjectFactory().newPrimitiveValueBuilder().
+ client.getObjectFactory().newComplexValue("Microsoft.Exchange.Services.OData.Model.ItemBody");
+ body.add(client.getObjectFactory().newPrimitiveProperty("Content",
+ client.getObjectFactory().newPrimitiveValueBuilder().
buildString("this is a simple email body content")));
- body.add(getClient().getObjectFactory().newEnumProperty("ContentType",
- getClient().getObjectFactory().newEnumValue("Microsoft.Exchange.Services.OData.Model.BodyType", "text")));
- message.getProperties().add(getClient().getObjectFactory().newComplexProperty("Body", body));
+ body.add(client.getObjectFactory().newEnumProperty("ContentType",
+ client.getObjectFactory().newEnumValue("Microsoft.Exchange.Services.OData.Model.BodyType", "text")));
+ message.getProperties().add(client.getObjectFactory().newComplexProperty("Body", body));
- final String actual = IOUtils.toString(getClient().getWriter().writeEntity(message, ContentType.JSON));
+ final String actual = IOUtils.toString(client.getWriter().writeEntity(message, ContentType.JSON));
final JsonNode expected =
OBJECT_MAPPER.readTree(IOUtils.toString(getClass().getResourceAsStream("olingo390.json")).
replace(Constants.JSON_NAVIGATION_LINK, Constants.JSON_BIND_LINK_SUFFIX));
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/test/java/org/apache/olingo/client/core/MetadataTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/MetadataTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/MetadataTest.java
index a24ca36..c150e64 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/MetadataTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/MetadataTest.java
@@ -26,7 +26,6 @@ import static org.junit.Assert.assertTrue;
import java.io.InputStream;
import java.util.List;
-import org.apache.olingo.client.api.ODataClient;
import org.apache.olingo.client.api.edm.xml.XMLMetadata;
import org.apache.olingo.commons.api.Constants;
import org.apache.olingo.commons.api.edm.Edm;
@@ -72,14 +71,9 @@ import org.junit.Test;
public class MetadataTest extends AbstractTest {
- @Override
- protected ODataClient getClient() {
- return v4Client;
- }
-
@Test
public void parse() {
- final Edm edm = getClient().getReader().readMetadata(getClass().getResourceAsStream("metadata.xml"));
+ final Edm edm = client.getReader().readMetadata(getClass().getResourceAsStream("metadata.xml"));
assertNotNull(edm);
// 1. Enum
@@ -140,7 +134,7 @@ public class MetadataTest extends AbstractTest {
@Test
public void demo() {
- final XMLMetadata metadata = getClient().getDeserializer(ContentType.APPLICATION_XML).
+ final XMLMetadata metadata = client.getDeserializer(ContentType.APPLICATION_XML).
toMetadata(getClass().getResourceAsStream("demo-metadata.xml"));
assertNotNull(metadata);
@@ -154,7 +148,7 @@ public class MetadataTest extends AbstractTest {
annots.getAnnotation("Org.OData.Publication.V1.PrivacyPolicyUrl").getExpression().asConstant().getValue());
// Now let's test some edm:Annotations
- final Edm edm = getClient().getReader().
+ final Edm edm = client.getReader().
readMetadata(getClass().getResourceAsStream("demo-metadata.xml"));
assertNotNull(edm);
@@ -181,7 +175,7 @@ public class MetadataTest extends AbstractTest {
@Test
public void multipleSchemas() {
- final XMLMetadata metadata = getClient().getDeserializer(ContentType.APPLICATION_XML).
+ final XMLMetadata metadata = client.getDeserializer(ContentType.APPLICATION_XML).
toMetadata(getClass().getResourceAsStream("northwind-metadata.xml"));
assertNotNull(metadata);
@@ -198,10 +192,10 @@ public class MetadataTest extends AbstractTest {
@Test
public void getContainerWithoutCallingGetSchemas() {
- final XMLMetadata metadata = getClient().getDeserializer(ContentType.APPLICATION_XML).
+ final XMLMetadata metadata = client.getDeserializer(ContentType.APPLICATION_XML).
toMetadata(getClass().getResourceAsStream("fromdoc1-metadata.xml"));
- Edm edm = getClient().getReader().readMetadata(metadata.getSchemaByNsOrAlias());
+ Edm edm = client.getReader().readMetadata(metadata.getSchemaByNsOrAlias());
assertNotNull(edm.getEntityContainer());
}
@@ -211,7 +205,7 @@ public class MetadataTest extends AbstractTest {
*/
@Test
public void fromdoc1() {
- final XMLMetadata metadata = getClient().getDeserializer(ContentType.APPLICATION_XML).
+ final XMLMetadata metadata = client.getDeserializer(ContentType.APPLICATION_XML).
toMetadata(getClass().getResourceAsStream("fromdoc1-metadata.xml"));
assertNotNull(metadata);
@@ -249,7 +243,7 @@ public class MetadataTest extends AbstractTest {
functionImport.getFunction());
// Now let's go high-level
- final Edm edm = getClient().getReader().readMetadata(getClass().getResourceAsStream("fromdoc1-metadata.xml"));
+ final Edm edm = client.getReader().readMetadata(getClass().getResourceAsStream("fromdoc1-metadata.xml"));
assertNotNull(edm);
List<EdmSchema> schemaList = edm.getSchemas();
@@ -291,7 +285,7 @@ public class MetadataTest extends AbstractTest {
*/
@Test
public void fromdoc2() {
- final XMLMetadata metadata = getClient().getDeserializer(ContentType.APPLICATION_XML)
+ final XMLMetadata metadata = client.getDeserializer(ContentType.APPLICATION_XML)
.toMetadata(getClass().getResourceAsStream("fromdoc2-metadata.xml"));
assertNotNull(metadata);
@@ -336,7 +330,7 @@ public class MetadataTest extends AbstractTest {
*/
@Test
public void fromdoc3() {
- final Edm edm = getClient().getReader().readMetadata(getClass().getResourceAsStream("fromdoc3-metadata.xml"));
+ final Edm edm = client.getReader().readMetadata(getClass().getResourceAsStream("fromdoc3-metadata.xml"));
assertNotNull(edm);
final EdmAnnotations group = edm.getSchema("Annotations").getAnnotationGroups().get(0);
@@ -354,7 +348,7 @@ public class MetadataTest extends AbstractTest {
*/
@Test
public void fromdoc4() {
- final XMLMetadata metadata = getClient().getDeserializer(ContentType.APPLICATION_XML).
+ final XMLMetadata metadata = client.getDeserializer(ContentType.APPLICATION_XML).
toMetadata(getClass().getResourceAsStream("fromdoc4-metadata.xml"));
assertNotNull(metadata);
@@ -382,7 +376,7 @@ public class MetadataTest extends AbstractTest {
assertTrue(urlRef.getValue().asDynamic().isApply());
// Now let's go high-level
- final Edm edm = getClient().getReader().readMetadata(getClass().getResourceAsStream("fromdoc4-metadata.xml"));
+ final Edm edm = client.getReader().readMetadata(getClass().getResourceAsStream("fromdoc4-metadata.xml"));
assertNotNull(edm);
final EdmAnnotations edmGroup = edm.getSchemas().get(0).getAnnotationGroups().get(0);
@@ -410,8 +404,7 @@ public class MetadataTest extends AbstractTest {
@Test
public void metadataWithCapabilities() throws Exception {
InputStream input = getClass().getResourceAsStream("Metadata-With-Capabilities.xml");
- final XMLMetadata metadata = getClient().getDeserializer(ContentType.APPLICATION_XML).
- toMetadata(input);
+ final XMLMetadata metadata = client.getDeserializer(ContentType.APPLICATION_XML).toMetadata(input);
CsdlSchema schema = metadata.getSchema("Capabilities");
assertNotNull(schema);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/test/java/org/apache/olingo/client/core/PrimitiveValueTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/PrimitiveValueTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/PrimitiveValueTest.java
index f46f272..3c31b55 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/PrimitiveValueTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/PrimitiveValueTest.java
@@ -18,31 +18,25 @@
*/
package org.apache.olingo.client.core;
-import org.apache.olingo.client.api.ODataClient;
+import static org.junit.Assert.assertEquals;
+
+import java.util.Calendar;
+
import org.apache.olingo.client.api.domain.ClientValue;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.junit.Test;
-import java.util.Calendar;
-
-import static org.junit.Assert.assertEquals;
-
public class PrimitiveValueTest extends AbstractTest {
- @Override
- protected ODataClient getClient() {
- return v4Client;
- }
-
@Test
public void timeOfDay() throws EdmPrimitiveTypeException {
final Calendar expected = Calendar.getInstance();
expected.clear();
expected.set(2013, 0, 10, 21, 45, 17);
- final ClientValue value = getClient().getObjectFactory().newPrimitiveValueBuilder().
- setType(EdmPrimitiveTypeKind.TimeOfDay).setValue(expected).build();
+ final ClientValue value = client.getObjectFactory().newPrimitiveValueBuilder()
+ .setType(EdmPrimitiveTypeKind.TimeOfDay).setValue(expected).build();
assertEquals(EdmPrimitiveTypeKind.TimeOfDay, value.asPrimitive().getTypeKind());
final Calendar actual = value.asPrimitive().toCastValue(Calendar.class);
@@ -59,8 +53,8 @@ public class PrimitiveValueTest extends AbstractTest {
expected.clear();
expected.set(2013, 0, 10);
- final ClientValue value = getClient().getObjectFactory().newPrimitiveValueBuilder().
- setType(EdmPrimitiveTypeKind.Date).setValue(expected).build();
+ final ClientValue value = client.getObjectFactory().newPrimitiveValueBuilder()
+ .setType(EdmPrimitiveTypeKind.Date).setValue(expected).build();
assertEquals(EdmPrimitiveTypeKind.Date, value.asPrimitive().getTypeKind());
final Calendar actual = value.asPrimitive().toCastValue(Calendar.class);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/test/java/org/apache/olingo/client/core/PropertyTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/PropertyTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/PropertyTest.java
index a545dc2..e7dc9ce 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/PropertyTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/PropertyTest.java
@@ -25,35 +25,29 @@ import static org.junit.Assert.assertTrue;
import java.io.InputStream;
import java.util.Iterator;
-import org.apache.olingo.client.api.ODataClient;
import org.apache.olingo.client.api.domain.ClientCollectionValue;
import org.apache.olingo.client.api.domain.ClientComplexValue;
import org.apache.olingo.client.api.domain.ClientProperty;
import org.apache.olingo.client.api.domain.ClientValue;
-import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.client.api.serialization.ODataDeserializerException;
import org.apache.olingo.client.api.serialization.ODataSerializerException;
+import org.apache.olingo.commons.api.format.ContentType;
import org.junit.Test;
public class PropertyTest extends AbstractTest {
- @Override
- protected ODataClient getClient() {
- return v4Client;
- }
-
private void _enum(final ContentType contentType) throws ODataDeserializerException, ODataSerializerException {
final InputStream input = getClass().getResourceAsStream("Products_5_SkinColor." + getSuffix(contentType));
- final ClientProperty property = getClient().getReader().readProperty(input, contentType);
+ final ClientProperty property = client.getReader().readProperty(input, contentType);
assertNotNull(property);
assertTrue(property.hasEnumValue());
- final ClientProperty written = getClient().getReader().readProperty(
- getClient().getWriter().writeProperty(property, contentType), contentType);
+ final ClientProperty written = client.getReader().readProperty(
+ client.getWriter().writeProperty(property, contentType), contentType);
// This is needed because type information gets lost with serialization
if (contentType.isCompatible(ContentType.APPLICATION_XML)) {
- final ClientProperty comparable = getClient().getObjectFactory().newEnumProperty(property.getName(),
- getClient().getObjectFactory().
+ final ClientProperty comparable = client.getObjectFactory().newEnumProperty(property.getName(),
+ client.getObjectFactory().
newEnumValue(property.getEnumValue().getTypeName(), written.getEnumValue().getValue()));
assertEquals(property, comparable);
@@ -72,21 +66,21 @@ public class PropertyTest extends AbstractTest {
private void complex(final ContentType contentType) throws ODataDeserializerException, ODataSerializerException {
final InputStream input = getClass().getResourceAsStream("Employees_3_HomeAddress." + getSuffix(contentType));
- final ClientProperty property = getClient().getReader().readProperty(input, contentType);
+ final ClientProperty property = client.getReader().readProperty(input, contentType);
assertNotNull(property);
assertTrue(property.hasComplexValue());
assertEquals(3, property.getComplexValue().size());
- final ClientProperty written = getClient().getReader().readProperty(
- getClient().getWriter().writeProperty(property, contentType), contentType);
+ final ClientProperty written = client.getReader().readProperty(
+ client.getWriter().writeProperty(property, contentType), contentType);
// This is needed because type information gets lost with JSON serialization
- final ClientComplexValue typedValue = getClient().getObjectFactory().
+ final ClientComplexValue typedValue = client.getObjectFactory().
newComplexValue(property.getComplexValue().getTypeName());
for (final Iterator<ClientProperty> itor = written.getComplexValue().iterator(); itor.hasNext();) {
final ClientProperty prop = itor.next();
typedValue.add(prop);
}
- final ClientProperty comparable = getClient().getObjectFactory().
+ final ClientProperty comparable = client.getObjectFactory().
newComplexProperty(property.getName(), typedValue);
assertEquals(property, comparable);
@@ -104,22 +98,22 @@ public class PropertyTest extends AbstractTest {
private void collection(final ContentType contentType) throws ODataDeserializerException, ODataSerializerException {
final InputStream input = getClass().getResourceAsStream("Products_5_CoverColors." + getSuffix(contentType));
- final ClientProperty property = getClient().getReader().readProperty(input, contentType);
+ final ClientProperty property = client.getReader().readProperty(input, contentType);
assertNotNull(property);
assertTrue(property.hasCollectionValue());
assertEquals(3, property.getCollectionValue().size());
- final ClientProperty written = getClient().getReader().readProperty(
- getClient().getWriter().writeProperty(property, contentType), contentType);
+ final ClientProperty written = client.getReader().readProperty(
+ client.getWriter().writeProperty(property, contentType), contentType);
// This is needed because type information gets lost with JSON serialization
if(contentType.isCompatible(ContentType.APPLICATION_XML)) {
- final ClientCollectionValue<ClientValue> typedValue = getClient().getObjectFactory().
+ final ClientCollectionValue<ClientValue> typedValue = client.getObjectFactory().
newCollectionValue(property.getCollectionValue().getTypeName());
for (final Iterator<ClientValue> itor = written.getCollectionValue().iterator(); itor.hasNext();) {
final ClientValue value = itor.next();
typedValue.add(value);
}
- final ClientProperty comparable = getClient().getObjectFactory().
+ final ClientProperty comparable = client.getObjectFactory().
newCollectionProperty(property.getName(), typedValue);
assertEquals(property, comparable);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/test/java/org/apache/olingo/client/core/ServiceDocumentTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/ServiceDocumentTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/ServiceDocumentTest.java
index ae06f90..7a66fac 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/ServiceDocumentTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/ServiceDocumentTest.java
@@ -24,7 +24,6 @@ import static org.junit.Assert.assertTrue;
import java.net.URI;
-import org.apache.olingo.client.api.ODataClient;
import org.apache.olingo.client.api.data.ResWrap;
import org.apache.olingo.client.api.data.ServiceDocument;
import org.apache.olingo.client.api.domain.ClientServiceDocument;
@@ -34,23 +33,14 @@ import org.junit.Test;
public class ServiceDocumentTest extends AbstractTest {
- @Override
- protected ODataClient getClient() {
- return v4Client;
- }
-
- private String getFileExtension(final ContentType contentType) {
- return contentType.isCompatible(ContentType.APPLICATION_XML) ? "xml" : "json";
- }
-
private ClientServiceDocument parse(final ContentType contentType) throws ODataDeserializerException {
- ResWrap<ServiceDocument> service = getClient().getDeserializer(contentType).toServiceDocument(
- getClass().getResourceAsStream("serviceDocument." + getFileExtension(contentType)));
+ ResWrap<ServiceDocument> service = client.getDeserializer(contentType).toServiceDocument(
+ getClass().getResourceAsStream("serviceDocument." + getSuffix(contentType)));
assertEquals(URI.create("http://host/service/$metadata"), service.getContextURL());
assertEquals("W/\"MjAxMy0wNS0xM1QxNDo1NFo=\"", service.getMetadataETag());
- final ClientServiceDocument serviceDocument = getClient().getBinder().getODataServiceDocument(service.getPayload());
+ final ClientServiceDocument serviceDocument = client.getBinder().getODataServiceDocument(service.getPayload());
assertNotNull(serviceDocument);
assertTrue(serviceDocument.getEntitySetNames().contains("Order Details"));
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/FilterFactoryTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/FilterFactoryTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/FilterFactoryTest.java
index 1d26f81..3b2c294 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/FilterFactoryTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/FilterFactoryTest.java
@@ -25,7 +25,6 @@ import java.net.URLEncoder;
import java.util.Calendar;
import java.util.TimeZone;
-import org.apache.olingo.client.api.ODataClient;
import org.apache.olingo.client.api.uri.FilterArgFactory;
import org.apache.olingo.client.api.uri.FilterFactory;
import org.apache.olingo.client.api.uri.URIFilter;
@@ -39,13 +38,8 @@ import org.junit.Test;
public class FilterFactoryTest extends AbstractTest {
- @Override
- protected ODataClient getClient() {
- return v4Client;
- }
-
private FilterFactory getFilterFactory() {
- return getClient().getFilterFactory();
+ return client.getFilterFactory();
}
private FilterArgFactory getFilterArgFactory() {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/URIBuilderTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/URIBuilderTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/URIBuilderTest.java
index 2af662f..5f9cc8b 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/URIBuilderTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/URIBuilderTest.java
@@ -26,32 +26,25 @@ import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
-import org.apache.olingo.client.api.ODataClient;
import org.apache.olingo.client.api.uri.QueryOption;
import org.apache.olingo.client.api.uri.URIBuilder;
import org.apache.olingo.client.core.AbstractTest;
-import org.apache.olingo.client.core.uri.ParameterAlias;
import org.junit.Test;
public class URIBuilderTest extends AbstractTest {
private static final String SERVICE_ROOT = "http://host/service";
- @Override
- protected ODataClient getClient() {
- return v4Client;
- }
-
@Test
public void metadata() throws URISyntaxException {
- final URI uri = getClient().newURIBuilder(SERVICE_ROOT).appendMetadataSegment().build();
+ final URI uri = client.newURIBuilder(SERVICE_ROOT).appendMetadataSegment().build();
assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/$metadata").build(), uri);
}
@Test
public void entity() throws URISyntaxException {
- final URI uri = getClient().newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("AnEntitySet").
+ final URI uri = client.newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("AnEntitySet").
appendKeySegment(11).build();
assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/AnEntitySet(11)").build(), uri);
@@ -59,21 +52,21 @@ public class URIBuilderTest extends AbstractTest {
final Map<String, Object> multiKey = new LinkedHashMap<String, Object>();
multiKey.put("OrderId", -10);
multiKey.put("ProductId", -10);
- URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
+ URIBuilder uriBuilder = client.newURIBuilder(SERVICE_ROOT).
appendEntitySetSegment("OrderLine").appendKeySegment(multiKey).
appendPropertySegment("Quantity").appendValueSegment();
assertEquals(new org.apache.http.client.utils.URIBuilder(
SERVICE_ROOT + "/OrderLine(OrderId=-10,ProductId=-10)/Quantity/$value").build(), uriBuilder.build());
- uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
+ uriBuilder = client.newURIBuilder(SERVICE_ROOT).
appendEntitySetSegment("Customer").appendKeySegment(-10).
select("CustomerId", "Name", "Orders").expand("Orders");
assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/Customer(-10)").
addParameter("$select", "CustomerId,Name,Orders").addParameter("$expand", "Orders").build(),
uriBuilder.build());
- uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
+ uriBuilder = client.newURIBuilder(SERVICE_ROOT).
appendEntitySetSegment("Customer").appendKeySegment(-10).appendNavigationSegment("Orders").appendRefSegment();
assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/Customer(-10)/Orders/$ref").build(),
uriBuilder.build());
@@ -81,7 +74,7 @@ public class URIBuilderTest extends AbstractTest {
@Test
public void expandWithOptions() throws URISyntaxException {
- final URI uri = getClient().newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").appendKeySegment(5).
+ final URI uri = client.newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").appendKeySegment(5).
expandWithOptions("ProductDetails", new LinkedHashMap<QueryOption, Object>() {
private static final long serialVersionUID = 3109256773218160485L;
@@ -96,7 +89,7 @@ public class URIBuilderTest extends AbstractTest {
}
public void expandWithLevels() throws URISyntaxException {
- final URI uri = getClient().newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").appendKeySegment(1).
+ final URI uri = client.newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").appendKeySegment(1).
expandWithOptions("Customer", Collections.<QueryOption, Object> singletonMap(QueryOption.LEVELS, 4)).
build();
@@ -106,11 +99,11 @@ public class URIBuilderTest extends AbstractTest {
@Test
public void count() throws URISyntaxException {
- URI uri = getClient().newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").count().build();
+ URI uri = client.newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").count().build();
assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/Products/$count").build(), uri);
- uri = getClient().newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").count(true).build();
+ uri = client.newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").count(true).build();
assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/Products").
addParameter("$count", "true").build(), uri);
@@ -118,34 +111,34 @@ public class URIBuilderTest extends AbstractTest {
@Test
public void filter() throws URISyntaxException {
- final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("AnEntitySet").
- filter(getClient().getFilterFactory().lt("VIN", 16));
+ final URIBuilder uriBuilder = client.newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("AnEntitySet").
+ filter(client.getFilterFactory().lt("VIN", 16));
assertEquals("http://host/service/AnEntitySet?%24filter=%28VIN%20lt%2016%29", uriBuilder.build().toASCIIString());
-// assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/AnEntitySet").
-// addParameter("$filter", "(VIN lt 16)").build(),
-// uriBuilder.build());
+ // assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/AnEntitySet").
+ // addParameter("$filter", "(VIN lt 16)").build(),
+ // uriBuilder.build());
}
@Test
public void filterWithParameter() throws URISyntaxException {
// http://host/service.svc/Employees?$filter=Region eq @p1&@p1='WA'
- final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Employees").
- filter(getClient().getFilterFactory().eq("Region", new ParameterAlias("p1"))).
+ final URIBuilder uriBuilder = client.newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Employees").
+ filter(client.getFilterFactory().eq("Region", new ParameterAlias("p1"))).
addParameterAlias("p1", "'WA'");
assertEquals("http://host/service/Employees?%24filter=%28Region%20eq%20%40p1%29&%40p1='WA'", uriBuilder.build()
.toASCIIString());
-// assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/Employees").
-// addParameter("$filter", "(Region eq @p1)").addParameter("@p1", "'WA'").build(),
-// uriBuilder.build());
+ // assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/Employees").
+ // addParameter("$filter", "(Region eq @p1)").addParameter("@p1", "'WA'").build(),
+ // uriBuilder.build());
}
@Test
public void expandMoreThenOnce() throws URISyntaxException {
- URI uri = getClient().newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").appendKeySegment(5).
+ URI uri = client.newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").appendKeySegment(5).
expand("Orders", "Customers").expand("Info").build();
assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/Products(5)").
@@ -154,7 +147,7 @@ public class URIBuilderTest extends AbstractTest {
@Test
public void selectMoreThenOnce() throws URISyntaxException {
- URI uri = getClient().newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Customers").appendKeySegment(5).
+ URI uri = client.newURIBuilder(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)").
@@ -163,7 +156,7 @@ public class URIBuilderTest extends AbstractTest {
@Test
public void singleton() throws URISyntaxException {
- final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
+ final URIBuilder uriBuilder = client.newURIBuilder(SERVICE_ROOT).
appendSingletonSegment("BestProductEverCreated");
assertEquals(new org.apache.http.client.utils.URIBuilder(
@@ -172,7 +165,7 @@ public class URIBuilderTest extends AbstractTest {
@Test
public void entityId() throws URISyntaxException {
- final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
+ final URIBuilder uriBuilder = client.newURIBuilder(SERVICE_ROOT).
appendEntityIdSegment("Products(0)");
assertEquals(new org.apache.http.client.utils.URIBuilder(
@@ -181,7 +174,7 @@ public class URIBuilderTest extends AbstractTest {
@Test
public void boundAction() throws URISyntaxException {
- final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
+ final URIBuilder uriBuilder = client.newURIBuilder(SERVICE_ROOT).
appendEntitySetSegment("Categories").appendKeySegment(1).
appendNavigationSegment("Products").
appendActionCallSegment("Model.AllOrders");
@@ -189,10 +182,10 @@ public class URIBuilderTest extends AbstractTest {
assertEquals(new org.apache.http.client.utils.URIBuilder(
SERVICE_ROOT + "/Categories(1)/Products/Model.AllOrders").build(), uriBuilder.build());
}
-
+
@Test
public void boundOperation() throws URISyntaxException {
- final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
+ final URIBuilder uriBuilder = client.newURIBuilder(SERVICE_ROOT).
appendEntitySetSegment("Categories").appendKeySegment(1).
appendNavigationSegment("Products").
appendOperationCallSegment("Model.AllOrders");
@@ -203,14 +196,14 @@ public class URIBuilderTest extends AbstractTest {
@Test
public void ref() throws URISyntaxException {
- URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
+ URIBuilder uriBuilder = client.newURIBuilder(SERVICE_ROOT).
appendEntitySetSegment("Categories").appendKeySegment(1).
appendNavigationSegment("Products").appendRefSegment();
assertEquals(new org.apache.http.client.utils.URIBuilder(
SERVICE_ROOT + "/Categories(1)/Products/$ref").build(), uriBuilder.build());
- uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
+ uriBuilder = client.newURIBuilder(SERVICE_ROOT).
appendEntitySetSegment("Categories").appendKeySegment(1).
appendNavigationSegment("Products").appendRefSegment().id("../../Products(0)");
@@ -221,7 +214,7 @@ public class URIBuilderTest extends AbstractTest {
@Test
public void derived() throws URISyntaxException {
- final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
+ final URIBuilder uriBuilder = client.newURIBuilder(SERVICE_ROOT).
appendEntitySetSegment("Customers").appendDerivedEntityTypeSegment("Model.VipCustomer").appendKeySegment(1);
assertEquals(new org.apache.http.client.utils.URIBuilder(
@@ -230,7 +223,7 @@ public class URIBuilderTest extends AbstractTest {
@Test
public void crossjoin() throws URISyntaxException {
- final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
+ final URIBuilder uriBuilder = client.newURIBuilder(SERVICE_ROOT).
appendCrossjoinSegment("Products", "Sales");
assertEquals(new org.apache.http.client.utils.URIBuilder(
@@ -239,7 +232,7 @@ public class URIBuilderTest extends AbstractTest {
@Test
public void all() throws URISyntaxException {
- final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).appendAllSegment();
+ final URIBuilder uriBuilder = client.newURIBuilder(SERVICE_ROOT).appendAllSegment();
assertEquals(new org.apache.http.client.utils.URIBuilder(
SERVICE_ROOT + "/$all").build(), uriBuilder.build());
@@ -247,7 +240,7 @@ public class URIBuilderTest extends AbstractTest {
@Test
public void search() throws URISyntaxException {
- final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
+ final URIBuilder uriBuilder = client.newURIBuilder(SERVICE_ROOT).
appendEntitySetSegment("Products").search("blue OR green");
assertEquals(new URI("http://host/service/Products?%24search=blue%20OR%20green"), uriBuilder.build());
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/geo/Geospatial.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/geo/Geospatial.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/geo/Geospatial.java
index 63d8b3f..860cbcc 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/geo/Geospatial.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/geo/Geospatial.java
@@ -72,7 +72,6 @@ public abstract class Geospatial {
* The OGIS geometry type number for feature collections.
*/
GEOSPATIALCOLLECTION
-
}
protected final Dimension dimension;
@@ -87,8 +86,8 @@ public abstract class Geospatial {
/**
* Constructor.
*
- * @param dimension dimension.
- * @param type type.
+ * @param dimension dimension
+ * @param type type
* @param srid SRID
*/
protected Geospatial(final Dimension dimension, final Type type, final SRID srid) {
@@ -129,7 +128,7 @@ public abstract class Geospatial {
/**
* Returns the {@link EdmPrimitiveTypeKind}
- * @return Edm primitve type kind
+ * @return EDM primitive type kind
*/
public abstract EdmPrimitiveTypeKind getEdmPrimitiveTypeKind();
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmNavigationPropertyImpl.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmNavigationPropertyImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmNavigationPropertyImpl.java
index bf5dbc6..05abab9 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmNavigationPropertyImpl.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmNavigationPropertyImpl.java
@@ -23,7 +23,6 @@ import java.util.Collections;
import java.util.List;
import org.apache.olingo.commons.api.edm.Edm;
-import org.apache.olingo.commons.api.edm.EdmElement;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmException;
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
@@ -32,7 +31,7 @@ import org.apache.olingo.commons.api.edm.EdmStructuredType;
import org.apache.olingo.commons.api.edm.provider.CsdlNavigationProperty;
import org.apache.olingo.commons.api.edm.provider.CsdlReferentialConstraint;
-public class EdmNavigationPropertyImpl extends AbstractEdmNamed implements EdmElement, EdmNavigationProperty {
+public class EdmNavigationPropertyImpl extends AbstractEdmNamed implements EdmNavigationProperty {
private final CsdlNavigationProperty navigationProperty;
private List<EdmReferentialConstraint> referentialConstraints;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmParameterImpl.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmParameterImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmParameterImpl.java
index 69af130..2f67761 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmParameterImpl.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmParameterImpl.java
@@ -19,7 +19,6 @@
package org.apache.olingo.commons.core.edm;
import org.apache.olingo.commons.api.edm.Edm;
-import org.apache.olingo.commons.api.edm.EdmElement;
import org.apache.olingo.commons.api.edm.EdmException;
import org.apache.olingo.commons.api.edm.EdmMapping;
import org.apache.olingo.commons.api.edm.EdmParameter;
@@ -27,7 +26,7 @@ import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.edm.geo.SRID;
import org.apache.olingo.commons.api.edm.provider.CsdlParameter;
-public class EdmParameterImpl extends AbstractEdmNamed implements EdmParameter, EdmElement {
+public class EdmParameterImpl extends AbstractEdmNamed implements EdmParameter {
private final CsdlParameter parameter;
private EdmType typeImpl;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java
index 5385d8a..67d0a21 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java
@@ -19,7 +19,6 @@
package org.apache.olingo.commons.core.edm;
import org.apache.olingo.commons.api.edm.Edm;
-import org.apache.olingo.commons.api.edm.EdmElement;
import org.apache.olingo.commons.api.edm.EdmException;
import org.apache.olingo.commons.api.edm.EdmMapping;
import org.apache.olingo.commons.api.edm.EdmProperty;
@@ -27,7 +26,7 @@ import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.edm.geo.SRID;
import org.apache.olingo.commons.api.edm.provider.CsdlProperty;
-public class EdmPropertyImpl extends AbstractEdmNamed implements EdmProperty, EdmElement {
+public class EdmPropertyImpl extends AbstractEdmNamed implements EdmProperty {
private final CsdlProperty property;
private EdmTypeInfo typeInfo;
@@ -59,7 +58,7 @@ public class EdmPropertyImpl extends AbstractEdmNamed implements EdmProperty, Ed
if (property.getType() == null) {
throw new EdmException("Property " + property.getName() + " must hava a full qualified type.");
}
- typeInfo = new EdmTypeInfo.Builder().setEdm(edm).setTypeExpression(property.getType().toString()).build();
+ typeInfo = new EdmTypeInfo.Builder().setEdm(edm).setTypeExpression(property.getType()).build();
}
@Override
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/BatchFacadeImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/BatchFacadeImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/BatchFacadeImpl.java
index 9fe52c8..98bf563 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/BatchFacadeImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/BatchFacadeImpl.java
@@ -33,20 +33,26 @@ import org.apache.olingo.server.core.deserializer.batch.BatchParserCommon;
public class BatchFacadeImpl implements BatchFacade {
private final BatchPartHandler partHandler;
- public BatchFacadeImpl(final ODataHandler oDataHandler, final ODataRequest request,
- final BatchProcessor batchProcessor, final boolean isStrict) {
+ /**
+ * Creates a new BatchFacade.
+ * @param oDataHandler handler
+ * @param batchProcessor batch processor
+ * @param isStrict mode switch (currently not used)
+ */
+ public BatchFacadeImpl(final ODataHandler oDataHandler, final BatchProcessor batchProcessor,
+ final boolean isStrict) {
partHandler = new BatchPartHandler(oDataHandler, batchProcessor, this);
}
@Override
- public ODataResponse handleODataRequest(final ODataRequest request) throws ODataApplicationException,
- ODataLibraryException {
+ public ODataResponse handleODataRequest(final ODataRequest request)
+ throws ODataApplicationException, ODataLibraryException {
return partHandler.handleODataRequest(request);
}
@Override
- public ODataResponsePart handleBatchRequest(final BatchRequestPart request) throws ODataApplicationException,
- ODataLibraryException {
+ public ODataResponsePart handleBatchRequest(final BatchRequestPart request)
+ throws ODataApplicationException, ODataLibraryException {
return partHandler.handleBatchRequest(request);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/BatchHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/BatchHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/BatchHandler.java
index ca253dc..121734e 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/BatchHandler.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/BatchHandler.java
@@ -46,7 +46,7 @@ public class BatchHandler {
throws ODataApplicationException, ODataLibraryException {
validateRequest(request);
- final BatchFacade operation = new BatchFacadeImpl(oDataHandler, request, batchProcessor, isStrict);
+ final BatchFacade operation = new BatchFacadeImpl(oDataHandler, batchProcessor, isStrict);
batchProcessor.processBatch(operation, request, response);
}
[19/22] olingo-odata4 git commit: OLINGO-864: Refining the Edm.Date
and Edm.Time behavior not to assume GMT but use default timezone of the JVM
Posted by mi...@apache.org.
OLINGO-864: Refining the Edm.Date and Edm.Time behavior not to assume GMT but use default timezone of the JVM
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/7b26cc6e
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/7b26cc6e
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/7b26cc6e
Branch: refs/heads/OLINGO-832_StreamSerializerPoC
Commit: 7b26cc6ee7515b4f2657fe9756862882ead7f26d
Parents: b317b90 f63bba7
Author: Ramesh Reddy <ra...@jboss.org>
Authored: Wed Feb 3 11:49:52 2016 -0600
Committer: Ramesh Reddy <ra...@jboss.org>
Committed: Wed Feb 10 13:04:42 2016 -0600
----------------------------------------------------------------------
.../client/AbstractParamTecSvcITCase.java | 14 +++++
.../commons/core/edm/primitivetype/EdmDate.java | 5 +-
.../edm/primitivetype/EdmDateTimeOffset.java | 62 ++++++++++++--------
.../core/edm/primitivetype/EdmTimeOfDay.java | 20 ++-----
.../core/edm/primitivetype/EdmDateTest.java | 1 -
.../primitivetype/EdmDateTimeOffsetTest.java | 9 ++-
.../edm/primitivetype/EdmTimeOfDayTest.java | 23 ++++++--
.../olingo/server/tecsvc/data/DataCreator.java | 10 +++-
.../server/tecsvc/data/DataProviderTest.java | 14 +++++
.../json/ODataJsonSerializerTest.java | 13 ++++
10 files changed, 116 insertions(+), 55 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7b26cc6e/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AbstractParamTecSvcITCase.java
----------------------------------------------------------------------
diff --cc fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AbstractParamTecSvcITCase.java
index d6e35a3,a4d8a67..dc2b940
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AbstractParamTecSvcITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AbstractParamTecSvcITCase.java
@@@ -63,4 -67,14 +67,14 @@@ public abstract class AbstractParamTecS
assertTrue(n instanceof Number);
assertEquals(value, ((Number) n).intValue());
}
+
+ @Before
+ public void setup() {
- DataProvider.setDefaultTimeZone("GMT");
++ TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+ }
+
+ @After
+ public void teardown() {
- DataProvider.setDefaultTimeZone(TimeZone.getDefault().getID());
++ TimeZone.setDefault(TimeZone.getDefault());
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7b26cc6e/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDate.java
----------------------------------------------------------------------
diff --cc lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDate.java
index 3eddca0,8588a5c..b0903ed
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDate.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDate.java
@@@ -48,7 -47,7 +47,7 @@@ public final class EdmDate extends Sing
final Boolean isNullable, final Integer maxLength, final Integer precision,
final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException {
- final Calendar dateTimeValue = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
- final Calendar dateTimeValue = Calendar.getInstance(EdmDateTimeOffset.getDefaultTimeZone());
++ final Calendar dateTimeValue = Calendar.getInstance();
dateTimeValue.clear();
final Matcher matcher = PATTERN.matcher(value);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7b26cc6e/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java
----------------------------------------------------------------------
diff --cc lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java
index a7f57d1,63c2c3c..990e1f5
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java
@@@ -203,21 -211,27 +211,27 @@@ public final class EdmDateTimeOffset ex
* @return the value as {@link Calendar}
* @throws EdmPrimitiveTypeException if the type of the value is not supported
*/
- protected static <T> Calendar createDateTime(final T value) throws EdmPrimitiveTypeException {
+ protected static <T> Calendar createDateTime(final T value, boolean isLocal) throws EdmPrimitiveTypeException {
Calendar dateTimeValue;
- if(value instanceof Time) {
- dateTimeValue = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
- dateTimeValue.setTimeInMillis(((Time) value).getTime());
- } else if (value instanceof Date) {
- // Although java.util.Date, as stated in its documentation,
- // "is intended to reflect coordinated universal time (UTC)",
- // its getName() method uses the default time zone. And so do we.
- dateTimeValue = Calendar.getInstance();
+ if (value instanceof Date) {
+ TimeZone tz;
+ if (isLocal) {
- tz = getDefaultTimeZone();
++ tz = TimeZone.getDefault();
+ } else {
+ tz = TimeZone.getTimeZone("GMT");
+ }
+ dateTimeValue = Calendar.getInstance(tz);
dateTimeValue.setTime((Date) value);
} else if (value instanceof Calendar) {
dateTimeValue = (Calendar) ((Calendar) value).clone();
} else if (value instanceof Long) {
- dateTimeValue = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+ TimeZone tz;
+ if (isLocal) {
- tz = getDefaultTimeZone();
++ tz = TimeZone.getDefault();
+ } else {
+ tz = TimeZone.getTimeZone("GMT");
+ }
+ dateTimeValue = Calendar.getInstance(tz);
dateTimeValue.setTimeInMillis((Long) value);
} else {
throw new EdmPrimitiveTypeException("The value type " + value.getClass() + " is not supported.");
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7b26cc6e/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java
----------------------------------------------------------------------
diff --cc lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java
index 7595e51,06ba239..de0d8d6
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java
@@@ -52,7 -51,7 +51,7 @@@ public final class EdmTimeOfDay extend
throw new EdmPrimitiveTypeException("The literal '" + value + "' has illegal content.");
}
- final Calendar dateTimeValue = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
- final Calendar dateTimeValue = Calendar.getInstance(EdmDateTimeOffset.getDefaultTimeZone());
++ final Calendar dateTimeValue = Calendar.getInstance();
dateTimeValue.clear();
dateTimeValue.set(Calendar.HOUR_OF_DAY, Byte.parseByte(matcher.group(1)));
dateTimeValue.set(Calendar.MINUTE, Byte.parseByte(matcher.group(2)));
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7b26cc6e/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java
----------------------------------------------------------------------
diff --cc lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java
index 5c60b38,5c60b38..3de7c37
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java
@@@ -28,7 -28,7 +28,6 @@@ import java.util.Calendar
import java.util.HashMap;
import java.util.List;
import java.util.Map;
--import java.util.TimeZone;
import java.util.UUID;
import org.apache.olingo.commons.api.Constants;
@@@ -1187,9 -1187,9 +1186,10 @@@ public class DataCreator
protected static Calendar getDateTime(final int year, final int month, final int day,
final int hour, final int minute, final int second) {
-- Calendar dateTime = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
++ Calendar dateTime = Calendar.getInstance();
dateTime.clear();
dateTime.set(year, month - 1, day, hour, minute, second);
++ dateTime.set(Calendar.MILLISECOND, 0);
return dateTime;
}
@@@ -1201,8 -1201,8 +1201,12 @@@
}
protected static Calendar getTime(final int hour, final int minute, final int second) {
-- Calendar time = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
++ Calendar time = Calendar.getInstance();
time.clear();
++ time.set(Calendar.YEAR, 1970);
++ time.set(Calendar.MONTH, Calendar.JANUARY);
++ time.set(Calendar.DAY_OF_MONTH, 1);
++ time.set(Calendar.MILLISECOND, 0);
time.set(Calendar.HOUR_OF_DAY, hour);
time.set(Calendar.MINUTE, minute);
time.set(Calendar.SECOND, second);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7b26cc6e/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/DataProviderTest.java
----------------------------------------------------------------------
diff --cc lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/DataProviderTest.java
index 6bd6463,b2bf587..dddafa2
--- a/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/DataProviderTest.java
+++ b/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/DataProviderTest.java
@@@ -52,6 -55,16 +55,16 @@@ public class DataProviderTest
private final EdmEntitySet esMixPrimCollComp = entityContainer.getEntitySet("ESMixPrimCollComp");
private final EdmEntitySet esMedia = entityContainer.getEntitySet("ESMedia");
+ @Before
+ public void setup() {
- DataProvider.setDefaultTimeZone("GMT");
++ TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+ }
+
+ @After
+ public void teardown() {
- DataProvider.setDefaultTimeZone(TimeZone.getDefault().getID());
- }
++ TimeZone.setDefault(TimeZone.getDefault());
++ }
+
@Test
public void esAllPrimEntity() throws Exception {
final DataProvider dataProvider = new DataProvider(oData, edm);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7b26cc6e/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
----------------------------------------------------------------------
diff --cc lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
index 7761b1d,7761b1d..8a7fca4
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
@@@ -22,6 -22,6 +22,7 @@@ import java.io.InputStream
import java.net.URI;
import java.util.Arrays;
import java.util.Collections;
++import java.util.TimeZone;
import org.apache.commons.io.IOUtils;
import org.apache.olingo.commons.api.data.ComplexValue;
@@@ -62,7 -62,7 +63,9 @@@ import org.apache.olingo.server.tecsvc.
import org.apache.olingo.server.tecsvc.data.DataProvider;
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
import org.hamcrest.CoreMatchers;
++import org.junit.After;
import org.junit.Assert;
++import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
@@@ -78,6 -78,6 +81,16 @@@ public class ODataJsonSerializerTest
new ODataJsonSerializer(ContentType.create(ContentType.JSON, ContentType.PARAMETER_IEEE754_COMPATIBLE, "true"));
private final UriHelper helper = odata.createUriHelper();
++ @Before
++ public void setup() {
++ TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
++ }
++
++ @After
++ public void teardown() {
++ TimeZone.setDefault(TimeZone.getDefault());
++ }
++
@Test
public void entitySimple() throws Exception {
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
[22/22] olingo-odata4 git commit: [OLINGO-832] Merge branch 'master'
into OLINGO-832_StreamSerializerPoC
Posted by mi...@apache.org.
[OLINGO-832] Merge branch 'master' into OLINGO-832_StreamSerializerPoC
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/67494a78
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/67494a78
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/67494a78
Branch: refs/heads/OLINGO-832_StreamSerializerPoC
Commit: 67494a789798911fee97388e204952ff4c357723
Parents: 5174f70 3c205f9
Author: mibo <mi...@apache.org>
Authored: Sat Feb 13 07:28:32 2016 +0100
Committer: mibo <mi...@apache.org>
Committed: Sat Feb 13 07:28:32 2016 +0100
----------------------------------------------------------------------
.../commons/AbstractInvocationHandler.java | 17 +-
.../AbstractStructuredInvocationHandler.java | 2 +-
.../commons/AnnotatationsInvocationHandler.java | 2 +-
.../ComplexCollectionInvocationHandler.java | 2 +-
.../proxy/commons/ComplexInvocationHandler.java | 6 +-
.../proxy/commons/EdmStreamValueHandler.java | 2 +-
.../EntityCollectionInvocationHandler.java | 2 +-
.../EntityContainerInvocationHandler.java | 4 +-
.../proxy/commons/EntityInvocationHandler.java | 6 +-
.../commons/EntitySetInvocationHandler.java | 2 +-
.../proxy/commons/InvokerInvocationHandler.java | 2 +-
.../commons/OperationInvocationHandler.java | 2 +-
.../PrimitiveCollectionInvocationHandler.java | 2 +-
...turedComposableInvokerInvocationHandler.java | 2 +-
.../olingo/ext/proxy/utils/CoreUtils.java | 5 +-
.../org/apache/olingo/fit/AbstractServices.java | 1947 --------------
.../main/java/org/apache/olingo/fit/Demo.java | 6 +-
.../java/org/apache/olingo/fit/OpenType.java | 5 +-
.../java/org/apache/olingo/fit/Services.java | 2511 +++++++++++++++---
.../org/apache/olingo/fit/Vocabularies.java | 10 +-
.../apache/olingo/fit/metadata/EntitySet.java | 8 -
.../olingo/fit/rest/OAuth2RequestFilter.java | 3 +-
.../fit/serializer/FITAtomDeserializer.java | 13 +-
.../olingo/fit/utils/AbstractUtilities.java | 22 +-
.../org/apache/olingo/fit/utils/Accept.java | 31 +-
.../org/apache/olingo/fit/utils/Commons.java | 24 +-
.../apache/olingo/fit/utils/ConstantKey.java | 10 +-
.../org/apache/olingo/fit/utils/Constants.java | 7 -
.../org/apache/olingo/fit/utils/FSManager.java | 25 +-
.../fit/utils/InjectableSerializerProvider.java | 42 -
.../apache/olingo/fit/utils/JSONUtilities.java | 14 +-
.../olingo/fit/utils/MetadataLinkInfo.java | 182 --
.../apache/olingo/fit/utils/XMLUtilities.java | 3 +
.../proxy/demo/odatademo/types/Customer.java | 6 +-
.../proxy/demo/odatademo/types/Employee.java | 6 +-
.../demo/odatademo/types/FeaturedProduct.java | 6 +-
.../opentypesservice/types/IndexedRow.java | 8 +-
.../odatawcfservice/types/CreditCardPI.java | 6 +-
.../odatawcfservice/types/Customer.java | 6 +-
.../odatawcfservice/types/Employee.java | 6 +-
.../odatawcfservice/types/PublicCompany.java | 8 +-
.../client/AbstractParamTecSvcITCase.java | 14 +
.../olingo/fit/tecsvc/client/BasicITCase.java | 34 +-
.../fit/tecsvc/client/BatchClientITCase.java | 8 +-
.../olingo/fit/tecsvc/client/BindingITCase.java | 10 +-
.../fit/tecsvc/client/DeepInsertITCase.java | 31 +-
.../tecsvc/client/EntityReferencesITCase.java | 13 +-
.../ExpandWithSystemQueryOptionsITCase.java | 74 +-
.../tecsvc/client/FilterSystemQueryITCase.java | 4 +-
.../core/domain/AbstractClientEntitySet.java | 114 -
.../core/domain/ClientCollectionValueImpl.java | 2 +-
.../client/core/domain/ClientEntitySetImpl.java | 74 +-
.../core/domain/ClientPrimitiveValueImpl.java | 5 +-
.../client/core/domain/ClientPropertyImpl.java | 135 +-
.../client/core/domain/ClientValuableImpl.java | 22 +-
.../core/serialization/ODataBinderImpl.java | 2 +-
.../apache/olingo/client/core/AbstractTest.java | 9 +-
.../org/apache/olingo/client/core/AtomTest.java | 6 -
.../olingo/client/core/EntitySetTest.java | 22 +-
.../apache/olingo/client/core/EntityTest.java | 73 +-
.../apache/olingo/client/core/ErrorTest.java | 8 +-
.../org/apache/olingo/client/core/JSONTest.java | 46 +-
.../apache/olingo/client/core/MetadataTest.java | 33 +-
.../olingo/client/core/PrimitiveValueTest.java | 22 +-
.../apache/olingo/client/core/PropertyTest.java | 38 +-
.../olingo/client/core/ServiceDocumentTest.java | 16 +-
.../client/core/uri/FilterFactoryTest.java | 8 +-
.../olingo/client/core/uri/URIBuilderTest.java | 71 +-
.../olingo/commons/api/edm/geo/Geospatial.java | 7 +-
.../commons/api/edm/provider/CsdlOnDelete.java | 23 +-
.../api/edm/provider/CsdlReturnType.java | 23 +-
.../olingo/commons/api/http/HttpHeader.java | 2 +
.../olingo/server/api/edmx/EdmxReference.java | 24 +-
.../commons/core/edm/EdmEntityTypeImpl.java | 7 +-
.../core/edm/EdmNavigationPropertyImpl.java | 3 +-
.../commons/core/edm/EdmParameterImpl.java | 3 +-
.../commons/core/edm/EdmPropertyImpl.java | 5 +-
.../commons/core/edm/primitivetype/EdmDate.java | 5 +-
.../edm/primitivetype/EdmDateTimeOffset.java | 62 +-
.../core/edm/primitivetype/EdmTimeOfDay.java | 20 +-
.../core/edm/primitivetype/EdmDateTest.java | 1 -
.../primitivetype/EdmDateTimeOffsetTest.java | 9 +-
.../edm/primitivetype/EdmTimeOfDayTest.java | 23 +-
.../edm/provider/EdmEntityTypeImplTest.java | 19 +
.../org/apache/olingo/server/api/OData.java | 10 +
.../uri/queryoption/SystemQueryOptionKind.java | 22 +-
.../apache/olingo/server/core/ErrorHandler.java | 47 +-
.../olingo/server/core/MetadataParser.java | 582 +++-
.../olingo/server/core/OData4HttpHandler.java | 10 +-
.../olingo/server/core/ReferenceResolver.java | 33 +
.../server/core/SchemaBasedEdmProvider.java | 137 +-
.../olingo/server/core/ServiceDispatcher.java | 48 +-
.../olingo/server/core/ServiceHandler.java | 27 +-
.../core/legacy/ProcessorServiceHandler.java | 12 +
.../server/core/requests/ActionRequest.java | 2 +-
.../server/core/requests/BatchRequest.java | 11 +-
.../server/core/requests/DataRequest.java | 6 +-
.../server/core/responses/EntityResponse.java | 1 +
.../core/responses/EntitySetResponse.java | 2 +
.../server/core/responses/ErrorResponse.java | 58 +
.../server/core/responses/MetadataResponse.java | 2 +
.../server/core/responses/PropertyResponse.java | 2 +
.../core/responses/ServiceDocumentResponse.java | 2 +
.../core/responses/ServiceResponseVisior.java | 4 +
.../resources/Org.OData.Capabilities.V1.xml | 388 +++
.../src/main/resources/Org.OData.Core.V1.xml | 187 ++
.../main/resources/Org.OData.Measures.V1.xml | 110 +
.../core/MetadataParserAnnotationsTest.java | 215 ++
.../olingo/server/core/MetadataParserTest.java | 3 +-
.../server/core/ServiceDispatcherTest.java | 17 +-
.../olingo/server/example/TripPinDataModel.java | 2 +-
.../olingo/server/example/TripPinHandler.java | 14 +-
.../server/example/TripPinServiceTest.java | 10 +
.../olingo/server/example/TripPinServlet.java | 11 +-
.../src/test/resources/annotations.xml | 153 ++
.../src/test/resources/trippin.xml | 808 +++---
.../apache/olingo/server/core/ODataHandler.java | 4 +-
.../server/core/ODataHttpHandlerImpl.java | 19 +-
.../apache/olingo/server/core/ODataImpl.java | 13 +
.../core/batchhandler/BatchFacadeImpl.java | 18 +-
.../server/core/batchhandler/BatchHandler.java | 2 +-
.../json/ODataJsonDeserializer.java | 77 +-
.../deserializer/xml/ODataXmlDeserializer.java | 84 +-
.../serializer/json/ODataJsonSerializer.java | 42 +-
.../core/serializer/xml/ODataXmlSerializer.java | 18 +-
.../olingo/server/core/uri/UriInfoImpl.java | 37 +-
.../server/core/uri/parser/ExpandParser.java | 30 +-
.../core/uri/parser/ExpressionParser.java | 85 +-
.../server/core/uri/parser/FilterParser.java | 6 +-
.../server/core/uri/parser/OrderByParser.java | 6 +-
.../olingo/server/core/uri/parser/Parser.java | 354 +--
.../server/core/uri/parser/ParserHelper.java | 168 +-
.../core/uri/parser/ResourcePathParser.java | 38 +-
.../server/core/uri/parser/SelectParser.java | 12 +-
.../server/core/uri/parser/UriTokenizer.java | 12 +-
.../uri/queryoption/expression/AliasImpl.java | 9 +-
.../uri/validator/UriValidationException.java | 4 +-
.../server/core/uri/validator/UriValidator.java | 513 +---
.../server-core-exceptions-i18n.properties | 1 +
.../olingo/server/core/uri/UriInfoImplTest.java | 50 +-
.../core/uri/parser/ExpressionParserTest.java | 2 +-
.../core/uri/parser/UriTokenizerTest.java | 3 +
.../olingo/server/tecsvc/data/DataCreator.java | 27 +-
.../olingo/server/tecsvc/data/DataProvider.java | 12 +-
.../SystemQueryOptionsRuntimeException.java | 3 +-
.../tecsvc/provider/ComplexTypeProvider.java | 8 +
.../tecsvc/provider/ContainerProvider.java | 6 +-
.../server/tecsvc/data/DataProviderTest.java | 14 +
.../AbstractODataDeserializerTest.java | 5 +-
.../ODataDeserializerEntityCollectionTest.java | 4 +-
...ataJsonDeserializerActionParametersTest.java | 2 +-
.../json/ODataJsonDeserializerEntityTest.java | 46 +-
...DataXMLDeserializerActionParametersTest.java | 2 +-
.../xml/ODataXmlDeserializerTest.java | 43 +-
.../json/ODataJsonSerializerTest.java | 47 +-
.../serializer/xml/ODataXmlSerializerTest.java | 77 +-
.../core/uri/parser/TestFullResourcePath.java | 112 +-
.../core/uri/queryoption/QueryOptionTest.java | 4 +-
.../queryoption/expression/ExpressionTest.java | 6 +-
.../core/uri/testutil/FilterValidator.java | 51 +-
.../core/uri/validator/UriValidatorTest.java | 68 +-
161 files changed, 6352 insertions(+), 4831 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/67494a78/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/67494a78/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/67494a78/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
----------------------------------------------------------------------
[15/22] olingo-odata4 git commit: OLINGO-865: fixing the bug with
extended complex types during serilization
Posted by mi...@apache.org.
OLINGO-865: fixing the bug with extended complex types during serilization
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/8468308a
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/8468308a
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/8468308a
Branch: refs/heads/OLINGO-832_StreamSerializerPoC
Commit: 8468308aeb2920e52d56b23101e59b3cf6b0e6f8
Parents: 280bc01
Author: Ramesh Reddy <ra...@jboss.org>
Authored: Sun Feb 7 17:06:22 2016 -0600
Committer: Ramesh Reddy <ra...@jboss.org>
Committed: Sun Feb 7 17:06:22 2016 -0600
----------------------------------------------------------------------
.../serializer/json/ODataJsonSerializer.java | 42 +++++++----
.../core/serializer/xml/ODataXmlSerializer.java | 18 +++--
.../olingo/server/tecsvc/data/DataCreator.java | 17 ++++-
.../tecsvc/provider/ComplexTypeProvider.java | 8 ++
.../json/ODataJsonSerializerTest.java | 34 ++++++++-
.../serializer/xml/ODataXmlSerializerTest.java | 77 +++++++++++++++++++-
6 files changed, 166 insertions(+), 30 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8468308a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
index a912862..3f3ba26 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
@@ -264,7 +264,7 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
if (!isODataMetadataNone && !resolvedType.equals(entityType)) {
json.writeStringField(Constants.JSON_TYPE, "#" + entity.getType());
}
- writeProperties(resolvedType, entity.getProperties(), select, json);
+ writeProperties(metadata, resolvedType, entity.getProperties(), select, json);
writeNavigationProperties(metadata, resolvedType, entity, expand, json);
json.writeEndObject();
}
@@ -318,7 +318,8 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
.getFullQualifiedName().getFullQualifiedNameAsString());
}
- protected void writeProperties(final EdmStructuredType type, final List<Property> properties,
+ protected void writeProperties(final ServiceMetadata metadata, final EdmStructuredType type,
+ final List<Property> properties,
final SelectOption select, final JsonGenerator json)
throws IOException, SerializerException {
final boolean all = ExpandSelectHelper.isAll(select);
@@ -330,7 +331,7 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
final Property property = findProperty(propertyName, properties);
final Set<List<String>> selectedPaths = all || edmProperty.isPrimitive() ? null :
ExpandSelectHelper.getSelectedPaths(select.getSelectItems(), propertyName);
- writeProperty(edmProperty, property, selectedPaths, json);
+ writeProperty(metadata, edmProperty, property, selectedPaths, json);
}
}
}
@@ -382,7 +383,7 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
}
}
- protected void writeProperty(final EdmProperty edmProperty, final Property property,
+ protected void writeProperty(final ServiceMetadata metadata, final EdmProperty edmProperty, final Property property,
final Set<List<String>> selectedPaths, final JsonGenerator json)
throws IOException, SerializerException {
json.writeFieldName(edmProperty.getName());
@@ -399,11 +400,11 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
}
}
} else {
- writePropertyValue(edmProperty, property, selectedPaths, json);
+ writePropertyValue(metadata, edmProperty, property, selectedPaths, json);
}
}
- private void writePropertyValue(final EdmProperty edmProperty,
+ private void writePropertyValue(final ServiceMetadata metadata, final EdmProperty edmProperty,
final Property property, final Set<List<String>> selectedPaths, final JsonGenerator json)
throws IOException, SerializerException {
final EdmType type = edmProperty.getType();
@@ -421,9 +422,10 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
}
} else if (property.isComplex()) {
if (edmProperty.isCollection()) {
- writeComplexCollection((EdmComplexType) type, property, selectedPaths, json);
+ writeComplexCollection(metadata, (EdmComplexType) type, property, selectedPaths, json);
} else {
- writeComplexValue((EdmComplexType) type, property.asComplex().getValue(), selectedPaths, json);
+ writeComplexValue(metadata, property, (EdmComplexType) type, property.asComplex().getValue(), selectedPaths,
+ json);
}
} else {
throw new SerializerException("Property type not yet supported!",
@@ -464,14 +466,15 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
json.writeEndArray();
}
- private void writeComplexCollection(final EdmComplexType type, final Property property,
+ private void writeComplexCollection(final ServiceMetadata metadata, final EdmComplexType type,
+ final Property property,
final Set<List<String>> selectedPaths, final JsonGenerator json)
throws IOException, SerializerException {
json.writeStartArray();
for (Object value : property.asCollection()) {
switch (property.getValueType()) {
case COLLECTION_COMPLEX:
- writeComplexValue(type, ((ComplexValue) value).getValue(), selectedPaths, json);
+ writeComplexValue(metadata, property, type, ((ComplexValue) value).getValue(), selectedPaths, json);
break;
default:
throw new SerializerException("Property type not yet supported!",
@@ -524,14 +527,23 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
}
}
- protected void writeComplexValue(final EdmComplexType type, final List<Property> properties,
+ protected void writeComplexValue(final ServiceMetadata metadata, final Property complexProperty,
+ final EdmComplexType type, final List<Property> properties,
final Set<List<String>> selectedPaths, final JsonGenerator json)
throws IOException, SerializerException {
json.writeStartObject();
- for (final String propertyName : type.getPropertyNames()) {
+
+ final EdmComplexType resolvedType = resolveComplexType(metadata,
+ type, complexProperty.getType());
+ if (!isODataMetadataNone && !resolvedType.equals(type)) {
+ json.writeStringField(Constants.JSON_TYPE,
+ "#" + complexProperty.getType());
+ }
+
+ for (final String propertyName : resolvedType.getPropertyNames()) {
final Property property = findProperty(propertyName, properties);
if (selectedPaths == null || ExpandSelectHelper.isSelected(selectedPaths, propertyName)) {
- writeProperty((EdmProperty) type.getProperty(propertyName), property,
+ writeProperty(metadata, (EdmProperty) resolvedType.getProperty(propertyName), property,
selectedPaths == null ? null : ExpandSelectHelper.getReducedSelectedPaths(selectedPaths, propertyName),
json);
}
@@ -610,7 +622,7 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
}
final List<Property> values =
property.isNull() ? Collections.<Property> emptyList() : property.asComplex().getValue();
- writeProperties(type, values, options == null ? null : options.getSelect(), json);
+ writeProperties(metadata, type, values, options == null ? null : options.getSelect(), json);
if (!property.isNull() && property.isComplex()) {
writeNavigationProperties(metadata, type, property.asComplex(),
options == null ? null : options.getExpand(), json);
@@ -677,7 +689,7 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
writeContextURL(contextURL, json);
writeMetadataETag(metadata, json);
json.writeFieldName(Constants.VALUE);
- writeComplexCollection(type, property, null, json);
+ writeComplexCollection(metadata, type, property, null, json);
json.writeEndObject();
json.close();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8468308a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
index 52d12e4..0057db4 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
@@ -635,8 +635,8 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
private String derivedComplexType(final EdmComplexType baseType,
final String definedType) throws SerializerException {
- String derived = baseType.getFullQualifiedName().getFullQualifiedNameAsString();
- if (derived.equals(definedType)) {
+ String base = baseType.getFullQualifiedName().getFullQualifiedNameAsString();
+ if (base.equals(definedType)) {
return null;
}
return definedType;
@@ -671,7 +671,7 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
} else {
writer.writeAttribute(METADATA, NS_METADATA, Constants.ATTR_TYPE,
"#" + complexType(metadata, (EdmComplexType) edmProperty.getType(), property.getType()));
- writeComplexValue(metadata, (EdmComplexType) edmProperty.getType(), property.asComplex().getValue(),
+ writeComplexValue(metadata, property, (EdmComplexType) edmProperty.getType(), property.asComplex().getValue(),
selectedPaths, writer);
}
} else {
@@ -717,7 +717,7 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
}
switch (property.getValueType()) {
case COLLECTION_COMPLEX:
- writeComplexValue(metadata, type, ((ComplexValue) value).getValue(), selectedPaths, writer);
+ writeComplexValue(metadata, property, type, ((ComplexValue) value).getValue(), selectedPaths, writer);
break;
default:
throw new SerializerException("Property type not yet supported!",
@@ -767,13 +767,17 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
}
}
- protected void writeComplexValue(final ServiceMetadata metadata, final EdmComplexType type,
+ protected void writeComplexValue(final ServiceMetadata metadata, Property complexProperty, final EdmComplexType type,
final List<Property> properties, final Set<List<String>> selectedPaths, final XMLStreamWriter writer)
throws XMLStreamException, SerializerException {
- for (final String propertyName : type.getPropertyNames()) {
+
+ final EdmComplexType resolvedType = resolveComplexType(metadata,
+ type, complexProperty.getType());
+
+ for (final String propertyName : resolvedType.getPropertyNames()) {
final Property property = findProperty(propertyName, properties);
if (selectedPaths == null || ExpandSelectHelper.isSelected(selectedPaths, propertyName)) {
- writeProperty(metadata, (EdmProperty) type.getProperty(propertyName), property,
+ writeProperty(metadata, (EdmProperty) resolvedType.getProperty(propertyName), property,
selectedPaths == null ? null : ExpandSelectHelper.getReducedSelectedPaths(selectedPaths, propertyName),
writer);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8468308a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java
index 5c60b38..80a3146 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java
@@ -44,6 +44,7 @@ import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.uri.UriHelper;
+import org.apache.olingo.server.tecsvc.provider.ComplexTypeProvider;
import org.apache.olingo.server.tecsvc.provider.EntityTypeProvider;
public class DataCreator {
@@ -1003,10 +1004,12 @@ public class DataCreator {
entity = new Entity();
entity.addProperty(createPrimitive("PropertyInt16", (short) 2));
- entity.addProperty(createComplex("PropertyComp",
- createComplex("PropertyComp",
+ entity.addProperty(createComplex("PropertyComp",
+ ComplexTypeProvider.nameCTCompCompExtended.getFullQualifiedNameAsString(),
+ createComplex("PropertyComp",
createPrimitive("PropertyInt16", (short) 987),
- createPrimitive("PropertyString", "String 2"))));
+ createPrimitive("PropertyString", "String 2")),
+ createPrimitive("PropertyDate", getDateTime(2012, 12, 3, 0, 0, 0))));
entityCollection.getEntities().add(entity);
setEntityType(entityCollection, edm.getEntityType(EntityTypeProvider.nameETCompComp));
@@ -1174,6 +1177,14 @@ public class DataCreator {
}
return new Property(null, name, ValueType.COMPLEX, complexValue);
}
+
+ protected static Property createComplex(final String name, final String type, final Property... properties) {
+ ComplexValue complexValue = new ComplexValue();
+ for (final Property property : properties) {
+ complexValue.getValue().add(property);
+ }
+ return new Property(type, name, ValueType.COMPLEX, complexValue);
+ }
protected static Property createComplexCollection(final String name, final List<Property>... propertiesList) {
List<ComplexValue> complexCollection = new ArrayList<ComplexValue>();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8468308a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ComplexTypeProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ComplexTypeProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ComplexTypeProvider.java
index 502f83a..7d539b6 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ComplexTypeProvider.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ComplexTypeProvider.java
@@ -38,6 +38,8 @@ public class ComplexTypeProvider {
public static final FullQualifiedName nameCTCompCollComp = new FullQualifiedName(SchemaProvider.NAMESPACE,
"CTCompCollComp");
public static final FullQualifiedName nameCTCompComp = new FullQualifiedName(SchemaProvider.NAMESPACE, "CTCompComp");
+ public static final FullQualifiedName nameCTCompCompExtended = new FullQualifiedName(
+ SchemaProvider.NAMESPACE, "CTCompCompExtended");
public static final FullQualifiedName nameCTCompNav = new FullQualifiedName(SchemaProvider.NAMESPACE, "CTCompNav");
public static final FullQualifiedName nameCTMixPrimCollComp = new FullQualifiedName(SchemaProvider.NAMESPACE,
@@ -125,6 +127,12 @@ public class ComplexTypeProvider {
.setName("CTCompComp")
.setProperties(Arrays.asList(PropertyProvider.propertyComp_CTTwoPrim));
+ } else if (complexTypeName.equals(nameCTCompCompExtended)) {
+ return new CsdlComplexType()
+ .setName("CTCompCompExtended")
+ .setBaseType(nameCTCompComp)
+ .setProperties(Arrays.asList(PropertyProvider.propertyDate));
+
} else if (complexTypeName.equals(nameCTCompCollComp)) {
return new CsdlComplexType()
.setName("CTCompCollComp")
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8468308a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
index 7761b1d..0ad7ac5 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
@@ -560,9 +560,38 @@ public class ODataJsonSerializerTest {
+ "\"@odata.metadataEtag\":\"W/\\\"metadataETag\\\"\","
+ "\"value\":["
+ "{\"PropertyComp\":{\"PropertyComp\":{\"PropertyString\":\"String 1\"}}},"
- + "{\"PropertyComp\":{\"PropertyComp\":{\"PropertyString\":\"String 2\"}}}]}",
+ + "{\"PropertyComp\":{\"@odata.type\":\"#olingo.odata.test1.CTCompCompExtended\","
+ + "\"PropertyComp\":{\"PropertyString\":\"String 2\"}}}]}",
resultString);
}
+
+ @Test
+ public void selectExtendedComplexType() throws Exception {
+ final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCompComp");
+ final EdmEntityType entityType = edmEntitySet.getEntityType();
+ final EntityCollection entitySet = data.readAll(edmEntitySet);
+ InputStream result = serializer
+ .entityCollection(metadata, entityType, entitySet,
+ EntityCollectionSerializerOptions.with()
+ .contextURL(ContextURL.with().entitySet(edmEntitySet)
+ .selectList(helper.buildContextURLSelectList(entityType, null, null))
+ .build())
+ .build()).getContent();
+ final String resultString = IOUtils.toString(result);
+
+ String expected = "{" +
+ "\"@odata.context\":\"$metadata#ESCompComp\"," +
+ "\"@odata.metadataEtag\":\"W/\\\"metadataETag\\\"\"," +
+ "\"value\":[" +
+ "{\"PropertyInt16\":1," +
+ "\"PropertyComp\":{\"PropertyComp\":{" +
+ "\"PropertyInt16\":123,\"PropertyString\":\"String 1\"}}}," +
+ "{\"PropertyInt16\":2," +
+ "\"PropertyComp\":{\"@odata.type\":\"#olingo.odata.test1.CTCompCompExtended\"," +
+ "\"PropertyComp\":{\"PropertyInt16\":987,\"PropertyString\":\"String 2\"},\"PropertyDate\":\"2012-12-03\"}}]}";
+ Assert.assertEquals(expected, resultString);
+
+ }
@Test
public void selectComplexTwice() throws Exception {
@@ -585,7 +614,8 @@ public class ODataJsonSerializerTest {
+ "\"@odata.metadataEtag\":\"W/\\\"metadataETag\\\"\","
+ "\"value\":["
+ "{\"PropertyComp\":{\"PropertyComp\":{\"PropertyInt16\":123,\"PropertyString\":\"String 1\"}}},"
- + "{\"PropertyComp\":{\"PropertyComp\":{\"PropertyInt16\":987,\"PropertyString\":\"String 2\"}}}]}",
+ + "{\"PropertyComp\":{\"@odata.type\":\"#olingo.odata.test1.CTCompCompExtended\","
+ + "\"PropertyComp\":{\"PropertyInt16\":987,\"PropertyString\":\"String 2\"}}}]}",
resultString);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8468308a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerTest.java
index 9611500..c904ea7 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerTest.java
@@ -1044,7 +1044,7 @@ public class ODataXmlSerializerTest {
" term=\"#olingo.odata.test1.ETCompComp\" />\n" +
" <a:content type=\"application/xml\">\n" +
" <m:properties>\n" +
- " <d:PropertyComp m:type=\"#olingo.odata.test1.CTCompComp\">\n" +
+ " <d:PropertyComp m:type=\"#olingo.odata.test1.CTCompCompExtended\">\n" +
" <d:PropertyComp m:type=\"#olingo.odata.test1.CTTwoPrim\">\n" +
" <d:PropertyString>String 2</d:PropertyString>\n" +
" </d:PropertyComp>\n" +
@@ -1057,6 +1057,77 @@ public class ODataXmlSerializerTest {
}
@Test
+ public void selectComplexExtended() throws Exception {
+ final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCompComp");
+ final EdmEntityType entityType = edmEntitySet.getEntityType();
+ final EntityCollection entitySet = data.readAll(edmEntitySet);
+ long currentTimeMillis = System.currentTimeMillis();
+ InputStream result = serializer
+ .entityCollection(metadata, entityType, entitySet,
+ EntityCollectionSerializerOptions.with()
+ .contextURL(ContextURL.with().entitySet(edmEntitySet)
+ .selectList(helper.buildContextURLSelectList(entityType, null, null))
+ .build())
+ .id("http://host/svc/ESCompComp")
+ .build()).getContent();
+ final String resultString = IOUtils.toString(result);
+ String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+ "<a:feed xmlns:a=\"http://www.w3.org/2005/Atom\" xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" "
+ + "xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\" m:context=\"$metadata#ESCompComp\" "
+ + "m:metadata-etag=\"metadataETag\">\n" +
+ " <a:id>http://host/svc/ESCompComp</a:id>\n" +
+ " <a:entry>\n" +
+ " <a:id>ESCompComp(1)</a:id>\n" +
+ " <a:title />\n" +
+ " <a:summary />\n" +
+ " <a:updated>"+ UPDATED_FORMAT.format(new Date(currentTimeMillis)) +"</a:updated>\n" +
+ " <a:author>\n" +
+ " <a:name />\n" +
+ " </a:author>\n" +
+ " <a:link rel=\"edit\" href=\"ESCompComp(1)\" />\n" +
+ " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" "
+ + "term=\"#olingo.odata.test1.ETCompComp\" />\n" +
+ " <a:content type=\"application/xml\">\n" +
+ " <m:properties>\n" +
+ " <d:PropertyInt16 m:type=\"Int16\">1</d:PropertyInt16>\n" +
+ " <d:PropertyComp m:type=\"#olingo.odata.test1.CTCompComp\">\n" +
+ " <d:PropertyComp m:type=\"#olingo.odata.test1.CTTwoPrim\">\n" +
+ " <d:PropertyInt16 m:type=\"Int16\">123</d:PropertyInt16>\n" +
+ " <d:PropertyString>String 1</d:PropertyString>\n" +
+ " </d:PropertyComp>\n" +
+ " </d:PropertyComp>\n" +
+ " </m:properties>\n" +
+ " </a:content>\n" +
+ " </a:entry>\n" +
+ " <a:entry>\n" +
+ " <a:id>ESCompComp(2)</a:id>\n" +
+ " <a:title />\n" +
+ " <a:summary />\n" +
+ " <a:updated>"+ UPDATED_FORMAT.format(new Date(currentTimeMillis)) +"</a:updated>\n" +
+ " <a:author>\n" +
+ " <a:name />\n" +
+ " </a:author>\n" +
+ " <a:link rel=\"edit\" href=\"ESCompComp(2)\" />\n" +
+ " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" "
+ + "term=\"#olingo.odata.test1.ETCompComp\" />\n" +
+ " <a:content type=\"application/xml\">\n" +
+ " <m:properties>\n" +
+ " <d:PropertyInt16 m:type=\"Int16\">2</d:PropertyInt16>\n" +
+ " <d:PropertyComp m:type=\"#olingo.odata.test1.CTCompCompExtended\">\n" +
+ " <d:PropertyComp m:type=\"#olingo.odata.test1.CTTwoPrim\">\n" +
+ " <d:PropertyInt16 m:type=\"Int16\">987</d:PropertyInt16>\n" +
+ " <d:PropertyString>String 2</d:PropertyString>\n" +
+ " </d:PropertyComp>\n" +
+ " <d:PropertyDate m:type=\"Date\">2012-12-03</d:PropertyDate>\n" +
+ " </d:PropertyComp>\n" +
+ " </m:properties>\n" +
+ " </a:content>\n" +
+ " </a:entry>\n" +
+ "</a:feed>";
+ checkXMLEqual(expected, resultString);
+ }
+
+ @Test
public void selectComplexTwice() throws Exception {
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCompComp");
final EdmEntityType entityType = edmEntitySet.getEntityType();
@@ -1117,7 +1188,7 @@ public class ODataXmlSerializerTest {
" term=\"#olingo.odata.test1.ETCompComp\" />\n" +
" <a:content type=\"application/xml\">\n" +
" <m:properties>\n" +
- " <d:PropertyComp m:type=\"#olingo.odata.test1.CTCompComp\">\n" +
+ " <d:PropertyComp m:type=\"#olingo.odata.test1.CTCompCompExtended\">\n" +
" <d:PropertyComp m:type=\"#olingo.odata.test1.CTTwoPrim\">\n" +
" <d:PropertyInt16 m:type=\"Int16\">987</d:PropertyInt16>\n" +
" <d:PropertyString>String 2</d:PropertyString>\n" +
@@ -1127,7 +1198,7 @@ public class ODataXmlSerializerTest {
" </a:content>\n" +
" </a:entry>\n" +
"</a:feed>\n";
- checkXMLEqual(expected, resultString);
+ checkXMLEqual(resultString, expected);
}
@Test
[02/22] olingo-odata4 git commit: OLINGO-864 refining date time
behavior
Posted by mi...@apache.org.
OLINGO-864 refining date time behavior
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/382ec16e
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/382ec16e
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/382ec16e
Branch: refs/heads/OLINGO-832_StreamSerializerPoC
Commit: 382ec16ee12dda57aa0ab527b45a59cf9b32be54
Parents: fbdf9aa
Author: shawkins <sh...@redhat.com>
Authored: Wed Feb 3 09:46:24 2016 -0500
Committer: shawkins <sh...@redhat.com>
Committed: Wed Feb 3 09:46:24 2016 -0500
----------------------------------------------------------------------
.../commons/core/edm/primitivetype/EdmDate.java | 5 +-
.../edm/primitivetype/EdmDateTimeOffset.java | 67 ++++++++++++++------
.../core/edm/primitivetype/EdmTimeOfDay.java | 19 ++----
.../core/edm/primitivetype/EdmDateTest.java | 1 -
.../primitivetype/EdmDateTimeOffsetTest.java | 4 +-
.../edm/primitivetype/EdmTimeOfDayTest.java | 41 +++++++++++-
6 files changed, 97 insertions(+), 40 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/382ec16e/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDate.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDate.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDate.java
index 71b747f..fb3f4ad 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDate.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDate.java
@@ -21,7 +21,6 @@ package org.apache.olingo.commons.core.edm.primitivetype;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import java.util.Calendar;
-import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -48,7 +47,7 @@ public final class EdmDate extends SingletonPrimitiveType {
final Boolean isNullable, final Integer maxLength, final Integer precision,
final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException {
- final Calendar dateTimeValue = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+ final Calendar dateTimeValue = Calendar.getInstance(EdmDateTimeOffset.getDefaultTimeZone());
dateTimeValue.clear();
final Matcher matcher = PATTERN.matcher(value);
@@ -75,7 +74,7 @@ public final class EdmDate extends SingletonPrimitiveType {
final Boolean isNullable, final Integer maxLength, final Integer precision,
final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
- final Calendar dateTimeValue = EdmDateTimeOffset.createDateTime(value);
+ final Calendar dateTimeValue = EdmDateTimeOffset.createDateTime(value, true);
final StringBuilder result = new StringBuilder(10); // Ten characters are enough for "normal" dates.
final int year = dateTimeValue.get(Calendar.YEAR);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/382ec16e/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java
index 6646c83..95b0fa5 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java
@@ -20,6 +20,7 @@ package org.apache.olingo.commons.core.edm.primitivetype;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
+import java.sql.Time;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.util.Calendar;
@@ -115,6 +116,7 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType {
/**
* Converts a {@link Calendar} value into the requested return type if possible.
+ * <br>It is expected that the {@link Calendar} value will already be in the desired time zone.
*
* @param dateTimeValue the value
* @param nanoSeconds nanoseconds part of the value; only used for the {@link Timestamp} return type
@@ -147,6 +149,20 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType {
Timestamp timestamp = new Timestamp(dateTimeValue.getTimeInMillis());
timestamp.setNanos(nanoSeconds);
return returnType.cast(timestamp);
+ } else if (returnType.isAssignableFrom(Time.class)) {
+ //normalize the value
+ dateTimeValue.set(Calendar.YEAR, 1970);
+ dateTimeValue.set(Calendar.MONTH, Calendar.JANUARY);
+ dateTimeValue.set(Calendar.DAY_OF_MONTH, 1);
+ dateTimeValue.set(Calendar.MILLISECOND, 0);
+ return returnType.cast(new Time(dateTimeValue.getTimeInMillis())); // may throw IllegalArgumentException
+ } else if (returnType.isAssignableFrom(java.sql.Date.class)) {
+ //normalize the value
+ dateTimeValue.set(Calendar.HOUR_OF_DAY, 0);
+ dateTimeValue.set(Calendar.MINUTE, 0);
+ dateTimeValue.set(Calendar.SECOND, 0);
+ dateTimeValue.set(Calendar.MILLISECOND, 0);
+ return returnType.cast(new java.sql.Date(dateTimeValue.getTimeInMillis())); // may throw IllegalArgumentException
} else {
throw new ClassCastException("unsupported return type " + returnType.getSimpleName());
}
@@ -157,18 +173,8 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType {
final Boolean isNullable, final Integer maxLength, final Integer precision,
final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
- final Calendar dateTimeValue;
- final int fractionalSecs;
- if (value instanceof Timestamp) {
- final Calendar tmp = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
- tmp.setTimeInMillis(((Timestamp) value).getTime());
- dateTimeValue = createDateTime(tmp);
- fractionalSecs = ((Timestamp) value).getNanos();
- } else {
- dateTimeValue = createDateTime(value);
- fractionalSecs = dateTimeValue.get(Calendar.MILLISECOND);
- }
-
+ final Calendar dateTimeValue = createDateTime(value, false);
+
final StringBuilder result = new StringBuilder();
final int year = dateTimeValue.get(Calendar.YEAR);
appendTwoDigits(result, year / 100);
@@ -186,8 +192,10 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType {
try {
if (value instanceof Timestamp) {
+ int fractionalSecs = ((Timestamp) value).getNanos();
appendFractionalSeconds(result, fractionalSecs, precision);
} else {
+ int fractionalSecs = dateTimeValue.get(Calendar.MILLISECOND);
appendMilliseconds(result, fractionalSecs, precision);
}
} catch (final IllegalArgumentException e) {
@@ -211,18 +219,27 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType {
* @return the value as {@link Calendar}
* @throws EdmPrimitiveTypeException if the type of the value is not supported
*/
- protected static <T> Calendar createDateTime(final T value) throws EdmPrimitiveTypeException {
+ protected static <T> Calendar createDateTime(final T value, boolean isLocal) throws EdmPrimitiveTypeException {
Calendar dateTimeValue;
if (value instanceof Date) {
- // Although java.util.Date, as stated in its documentation,
- // "is intended to reflect coordinated universal time (UTC)",
- // its toString() method uses the default time zone. And so do we.
- dateTimeValue = Calendar.getInstance();
+ TimeZone tz;
+ if (isLocal) {
+ tz = getDefaultTimeZone();
+ } else {
+ tz = TimeZone.getTimeZone("GMT");
+ }
+ dateTimeValue = Calendar.getInstance(tz);
dateTimeValue.setTime((Date) value);
} else if (value instanceof Calendar) {
dateTimeValue = (Calendar) ((Calendar) value).clone();
} else if (value instanceof Long) {
- dateTimeValue = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+ TimeZone tz;
+ if (isLocal) {
+ tz = getDefaultTimeZone();
+ } else {
+ tz = TimeZone.getTimeZone("GMT");
+ }
+ dateTimeValue = Calendar.getInstance(tz);
dateTimeValue.setTimeInMillis((Long) value);
} else {
throw new EdmPrimitiveTypeException("The value type " + value.getClass() + " is not supported.");
@@ -300,4 +317,18 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType {
result.append('.').append(formatted.substring(0, actualLength));
}
}
+
+ /**
+ * When the Timezone information is absent on the date time types, like EdmDate, EDMTimeOfDay, EdmDateTimeOffset
+ * this method defines the default timezone that should be used parse and output payload.
+ * User should set system property "defaultTimeZoneForEdmDateTypes" to control this. The default would be
+ * Java VM default if not defined.
+ *
+ * @return Timezone
+ */
+ protected static TimeZone getDefaultTimeZone() {
+ String tz = System.getProperty("defaultTimeZoneForEdmDateTypes");
+ return (tz != null)?TimeZone.getTimeZone(tz):TimeZone.getDefault();
+ }
+
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/382ec16e/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java
index fb10e02..3090761 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java
@@ -22,7 +22,6 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import java.sql.Timestamp;
import java.util.Calendar;
-import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -52,7 +51,7 @@ public final class EdmTimeOfDay extends SingletonPrimitiveType {
throw new EdmPrimitiveTypeException("The literal '" + value + "' has illegal content.");
}
- final Calendar dateTimeValue = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+ final Calendar dateTimeValue = Calendar.getInstance(EdmDateTimeOffset.getDefaultTimeZone());
dateTimeValue.clear();
dateTimeValue.set(Calendar.HOUR_OF_DAY, Byte.parseByte(matcher.group(1)));
dateTimeValue.set(Calendar.MINUTE, Byte.parseByte(matcher.group(2)));
@@ -92,18 +91,8 @@ public final class EdmTimeOfDay extends SingletonPrimitiveType {
final Boolean isNullable, final Integer maxLength, final Integer precision,
final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
- final Calendar dateTimeValue;
- final int fractionalSecs;
- if (value instanceof Timestamp) {
- final Calendar tmp = Calendar.getInstance();
- tmp.setTimeInMillis(((Timestamp) value).getTime());
- dateTimeValue = EdmDateTimeOffset.createDateTime(tmp);
- fractionalSecs = ((Timestamp) value).getNanos();
- } else {
- dateTimeValue = EdmDateTimeOffset.createDateTime(value);
- fractionalSecs = dateTimeValue.get(Calendar.MILLISECOND);
- }
-
+ final Calendar dateTimeValue = EdmDateTimeOffset.createDateTime(value, true);
+
final StringBuilder result = new StringBuilder();
EdmDateTimeOffset.appendTwoDigits(result, dateTimeValue.get(Calendar.HOUR_OF_DAY));
result.append(':');
@@ -113,8 +102,10 @@ public final class EdmTimeOfDay extends SingletonPrimitiveType {
try {
if (value instanceof Timestamp) {
+ int fractionalSecs = ((Timestamp) value).getNanos();
EdmDateTimeOffset.appendFractionalSeconds(result, fractionalSecs, precision);
} else {
+ int fractionalSecs = dateTimeValue.get(Calendar.MILLISECOND);
EdmDateTimeOffset.appendMilliseconds(result, fractionalSecs, precision);
}
} catch (final IllegalArgumentException e) {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/382ec16e/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTest.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTest.java b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTest.java
index 6e10d2b..26b6a49 100644
--- a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTest.java
+++ b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTest.java
@@ -67,7 +67,6 @@ public class EdmDateTest extends PrimitiveTypeBaseTest {
public void valueOfString() throws Exception {
Calendar dateTime = Calendar.getInstance();
dateTime.clear();
- dateTime.setTimeZone(TimeZone.getTimeZone("GMT"));
dateTime.set(2012, 1, 29);
assertEquals(dateTime, instance.valueOfString("2012-02-29", null, null, null, null, null, Calendar.class));
assertEquals(Long.valueOf(dateTime.getTimeInMillis()), instance.valueOfString("2012-02-29", null, null, null, null,
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/382ec16e/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java
index 3013916..0b51925 100644
--- a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java
+++ b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java
@@ -28,7 +28,6 @@ import java.util.Date;
import java.util.TimeZone;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
public class EdmDateTimeOffsetTest extends PrimitiveTypeBaseTest {
@@ -77,8 +76,7 @@ public class EdmDateTimeOffsetTest extends PrimitiveTypeBaseTest {
assertEquals("1969-12-31T23:59:59.98Z", instance.valueToString(-20L, null, null, 2, null, null));
final Date date = new Date(millis);
- final String time = date.toString().substring(11, 19);
- assertTrue(instance.valueToString(date, null, null, 3, null, null).contains(time));
+ assertEquals("2012-02-29T23:32:03.007Z", instance.valueToString(date, null, null, 3, null, null));
expectFacetsErrorInValueToString(instance, millis, null, null, null, null, null);
expectFacetsErrorInValueToString(instance, 3L, null, null, 2, null, null);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/382ec16e/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDayTest.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDayTest.java b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDayTest.java
index 917814d..57dd5d9 100644
--- a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDayTest.java
+++ b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDayTest.java
@@ -22,6 +22,7 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.junit.Test;
+import java.sql.Time;
import java.util.Calendar;
import java.util.TimeZone;
@@ -60,12 +61,50 @@ public class EdmTimeOfDayTest extends PrimitiveTypeBaseTest {
expectTypeErrorInValueToString(instance, 0);
}
+
+ @Test
+ public void valueToStringWithGMT() throws Exception {
+ Calendar dateTime = Calendar.getInstance();
+ dateTime.clear();
+ dateTime.setTimeZone(TimeZone.getTimeZone("GMT+11:30"));
+ dateTime.set(1, 2, 3, 4, 5, 6);
+ assertEquals("04:05:06", instance.valueToString(dateTime, null, null, null, null, null));
+ }
+
+ @Test
+ public void testRoundTripTime() throws Exception {
+ java.sql.Time time = instance.valueOfString("04:05:06.002", true,
+ 4000, 3, 0, true, java.sql.Time.class);
+ String val = instance.valueToString(time, true, 4000, 3, 0, true);
+ assertEquals("04:05:06", val);
+ }
+
+ @Test
+ public void toTimeObject() throws Exception {
+ Calendar dateTime = Calendar.getInstance();
+ dateTime.clear();
+ dateTime.set(Calendar.HOUR, 12);
+
+ Time timeValue = instance.valueOfString("12:00:00", null, null, null, null, null, Time.class);
+ assertEquals(dateTime.getTimeInMillis(), timeValue.getTime());
+ }
+
+ @Test
+ public void fromTimeObject() throws Exception {
+ Calendar dateTime = Calendar.getInstance();
+ dateTime.clear();
+ dateTime.set(Calendar.HOUR, 5);
+ dateTime.set(Calendar.MINUTE, 59);
+ dateTime.set(Calendar.SECOND, 23);
+
+ Time time = new Time(dateTime.getTimeInMillis());
+ assertEquals("05:59:23", instance.valueToString(time, null, null, null, null, null));
+ }
@Test
public void valueOfString() throws Exception {
Calendar dateTime = Calendar.getInstance();
dateTime.clear();
- dateTime.setTimeZone(TimeZone.getTimeZone("GMT"));
assertEquals(dateTime, instance.valueOfString("00:00", null, null, null, null, null, Calendar.class));
assertEquals(dateTime, instance.valueOfString("00:00:00", null, null, null, null, null, Calendar.class));
[07/22] olingo-odata4 git commit: [OLINGO-852] less warnings +
general clean-up
Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/Vocabularies.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/Vocabularies.java b/fit/src/main/java/org/apache/olingo/fit/Vocabularies.java
index 0390eae..c13bf35 100644
--- a/fit/src/main/java/org/apache/olingo/fit/Vocabularies.java
+++ b/fit/src/main/java/org/apache/olingo/fit/Vocabularies.java
@@ -27,7 +27,6 @@ import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
import org.apache.olingo.fit.metadata.Metadata;
import org.apache.olingo.fit.utils.Accept;
import org.apache.olingo.fit.utils.ConstantKey;
@@ -43,8 +42,8 @@ public class Vocabularies {
private final XMLUtilities xml;
public Vocabularies() throws IOException {
- Metadata metadata = new Metadata(FSManager.instance(ODataServiceVersion.V40).readRes(
- "vocabularies-" + Constants.get(ConstantKey.METADATA), Accept.XML));
+ Metadata metadata = new Metadata(FSManager.instance()
+ .readRes("vocabularies-" + Constants.get(ConstantKey.METADATA), Accept.XML));
xml = new XMLUtilities(metadata);
}
@@ -55,8 +54,7 @@ public class Vocabularies {
try {
return xml.createResponse(
null,
- FSManager.instance(ODataServiceVersion.V40).readRes(
- "vocabularies-" + Constants.get(ConstantKey.METADATA), Accept.XML),
+ FSManager.instance().readRes("vocabularies-" + Constants.get(ConstantKey.METADATA), Accept.XML),
null,
Accept.XML);
} catch (Exception e) {
@@ -71,7 +69,7 @@ public class Vocabularies {
try {
return xml.createResponse(
null,
- FSManager.instance(ODataServiceVersion.V40).readFile(vocabulary, null),
+ FSManager.instance().readFile(vocabulary, null),
null,
Accept.XML);
} catch (Exception e) {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/metadata/EntitySet.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/metadata/EntitySet.java b/fit/src/main/java/org/apache/olingo/fit/metadata/EntitySet.java
index 15285d2..c165bb7 100644
--- a/fit/src/main/java/org/apache/olingo/fit/metadata/EntitySet.java
+++ b/fit/src/main/java/org/apache/olingo/fit/metadata/EntitySet.java
@@ -24,18 +24,10 @@ import java.util.Map;
public class EntitySet extends AbstractMetadataElement {
private final String name;
-
private String type;
-
private final boolean singleton;
-
- // --------------------------
- // V4 only
- // --------------------------
private final Map<String, String> binding;
- // --------------------------
-
public EntitySet(final String name, final boolean singleton) {
this.name = name;
this.singleton = singleton;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/rest/OAuth2RequestFilter.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/rest/OAuth2RequestFilter.java b/fit/src/main/java/org/apache/olingo/fit/rest/OAuth2RequestFilter.java
index 17476dd..a7ab945 100644
--- a/fit/src/main/java/org/apache/olingo/fit/rest/OAuth2RequestFilter.java
+++ b/fit/src/main/java/org/apache/olingo/fit/rest/OAuth2RequestFilter.java
@@ -19,14 +19,13 @@
package org.apache.olingo.fit.rest;
import javax.ws.rs.container.ContainerRequestContext;
-import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.ext.Provider;
import org.apache.commons.lang3.StringUtils;
import org.apache.cxf.rs.security.oauth2.filters.OAuthRequestFilter;
@Provider
-public class OAuth2RequestFilter extends OAuthRequestFilter implements ContainerRequestFilter {
+public class OAuth2RequestFilter extends OAuthRequestFilter {
@Override
public void filter(final ContainerRequestContext context) {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/serializer/FITAtomDeserializer.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/serializer/FITAtomDeserializer.java b/fit/src/main/java/org/apache/olingo/fit/serializer/FITAtomDeserializer.java
index d02475d..357dc5a 100644
--- a/fit/src/main/java/org/apache/olingo/fit/serializer/FITAtomDeserializer.java
+++ b/fit/src/main/java/org/apache/olingo/fit/serializer/FITAtomDeserializer.java
@@ -21,7 +21,6 @@ package org.apache.olingo.fit.serializer;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import javax.xml.stream.XMLEventReader;
@@ -32,19 +31,15 @@ import org.apache.olingo.commons.api.Constants;
public class FITAtomDeserializer extends AtomDeserializer {
- private static final Charset ENCODING = Charset.forName(Constants.UTF8);
-
public FITAtomDeserializer() {
super();
}
@Override
protected XMLEventReader getReader(final InputStream input) throws XMLStreamException {
- final CharsetDecoder decoder = ENCODING.newDecoder();
- decoder.onMalformedInput(CodingErrorAction.IGNORE);
- decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
-
- return FACTORY.createXMLEventReader(new InputStreamReader(input, decoder));
+ return FACTORY.createXMLEventReader(new InputStreamReader(input,
+ Charset.forName(Constants.UTF8).newDecoder()
+ .onMalformedInput(CodingErrorAction.IGNORE)
+ .onUnmappableCharacter(CodingErrorAction.IGNORE)));
}
-
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
index ee87eb0..a14cb8b 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
@@ -34,7 +34,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
-import java.util.regex.Pattern;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.core.Response;
@@ -70,38 +69,19 @@ public abstract class AbstractUtilities {
*/
protected static final Logger LOG = LoggerFactory.getLogger(AbstractUtilities.class);
- protected static final Pattern ENTITY_URI_PATTERN = Pattern.compile(".*\\/.*\\(.*\\)");
-
- /**
- * Batch/Changeset content type.
- */
- public static final String MULTIPART_CONTENT_TYPE = "multipart/mixed";
-
- /**
- * Batch item content type.
- */
- public static final String ITEM_CONTENT_TYPE = "application/http";
-
- /**
- * Boundary key.
- */
- public static final String BOUNDARY = "boundary";
-
protected final Metadata metadata;
protected final FSManager fsManager;
protected final ODataDeserializer atomDeserializer;
-
protected final ODataDeserializer jsonDeserializer;
protected final ODataSerializer atomSerializer;
-
protected final ODataSerializer jsonSerializer;
public AbstractUtilities(final Metadata metadata) throws IOException {
this.metadata = metadata;
- fsManager = FSManager.instance(ODataServiceVersion.V40);
+ fsManager = FSManager.instance();
atomDeserializer = new FITAtomDeserializer();
jsonDeserializer = new JsonDeserializer(true);
atomSerializer = new AtomSerializer(true);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/utils/Accept.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/Accept.java b/fit/src/main/java/org/apache/olingo/fit/utils/Accept.java
index 5f9a724..9acda31 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/Accept.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/Accept.java
@@ -20,33 +20,31 @@ package org.apache.olingo.fit.utils;
import java.util.regex.Pattern;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.http.entity.ContentType;
+import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.fit.UnsupportedMediaTypeException;
public enum Accept {
- TEXT(ContentType.TEXT_PLAIN.getMimeType(), ".txt"),
- XML(ContentType.APPLICATION_XML.getMimeType(), ".xml"),
- ATOM(ContentType.APPLICATION_ATOM_XML.getMimeType(), ".xml"),
- JSON(ContentType.APPLICATION_JSON.getMimeType() + ";odata.metadata=minimal", ".full.json"),
- JSON_NOMETA(ContentType.APPLICATION_JSON.getMimeType() + ";odata.metadata=none", ".full.json"),
- JSON_FULLMETA(ContentType.APPLICATION_JSON.getMimeType() + ";odata.metadata=full", ".full.json");
+ TEXT(ContentType.TEXT_PLAIN, ".txt"),
+ XML(ContentType.APPLICATION_XML, ".xml"),
+ ATOM(ContentType.APPLICATION_ATOM_XML, ".xml"),
+ JSON(ContentType.JSON, ".full.json"),
+ JSON_NOMETA(ContentType.JSON_NO_METADATA, ".full.json"),
+ JSON_FULLMETA(ContentType.JSON_FULL_METADATA, ".full.json");
- private final String contentTypeV4;
+ private static Pattern allTypesPattern = Pattern.compile("(.*,)?\\*/\\*([,;].*)?");
+ private final ContentType contentType;
private final String fileExtension;
- private static Pattern allTypesPattern = Pattern.compile("(.*,)?\\*/\\*([,;].*)?");
-
- Accept(final String contentTypeV4, final String fileExtension) {
- this.contentTypeV4 = contentTypeV4;
+ Accept(final ContentType contentType, final String fileExtension) {
+ this.contentType = contentType;
this.fileExtension = fileExtension;
}
@Override
public String toString() {
- return contentTypeV4;
+ return contentType.toContentTypeString();
}
public String getExtension() {
@@ -58,15 +56,14 @@ public enum Accept {
}
public static Accept parse(final String contentType, final Accept def) {
- if (StringUtils.isBlank(contentType) || allTypesPattern.matcher(contentType).matches()) {
+ if (contentType == null || contentType.isEmpty() || allTypesPattern.matcher(contentType).matches()) {
return def;
} else if (contentType.startsWith(JSON_NOMETA.toString())) {
return JSON_NOMETA;
} else if (contentType.startsWith(JSON_FULLMETA.toString())) {
return JSON_FULLMETA;
} else if (contentType.startsWith(JSON.toString())
- || contentType.startsWith(ContentType.APPLICATION_JSON.getMimeType())) {
-
+ || contentType.startsWith(ContentType.APPLICATION_JSON.toContentTypeString())) {
return JSON;
} else if (contentType.startsWith(XML.toString())) {
return XML;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java b/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java
index 32644d9..5ee4d25 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java
@@ -27,7 +27,6 @@ import java.net.URI;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.EnumMap;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -40,7 +39,6 @@ import org.apache.commons.lang3.tuple.Pair;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
import org.apache.olingo.fit.metadata.Metadata;
-import org.codehaus.plexus.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -59,9 +57,6 @@ public abstract class Commons {
*/
protected static final Logger LOG = LoggerFactory.getLogger(Commons.class);
- private static final EnumMap<ODataServiceVersion, Metadata> METADATA =
- new EnumMap<ODataServiceVersion, Metadata>(ODataServiceVersion.class);
-
protected static final Pattern MULTIKEY_PATTERN = Pattern.compile("(.*=.*,?)+");
protected static final Map<String, Integer> SEQUENCE = new HashMap<String, Integer>();
@@ -99,14 +94,11 @@ public abstract class Commons {
new ImmutablePair<String, EdmPrimitiveTypeKind>("ID", EdmPrimitiveTypeKind.Guid));
}
- public static Metadata getMetadata(final ODataServiceVersion version) {
- if (!METADATA.containsKey(version)) {
- final InputStream is = Commons.class.getResourceAsStream("/" + version.name() + "/metadata.xml");
-
- METADATA.put(version, new Metadata(is));
- }
+ private static final Metadata METADATA =
+ new Metadata(Commons.class.getResourceAsStream("/" + ODataServiceVersion.V40.name() + "/metadata.xml"));
- return METADATA.get(version);
+ public static Metadata getMetadata() {
+ return METADATA;
}
public static Map<String, Pair<String, EdmPrimitiveTypeKind>> getMediaContent() {
@@ -115,13 +107,13 @@ public abstract class Commons {
public static String getEntityURI(final String entitySetName, final String entityKey) {
// expected singleton in case of null key
- return entitySetName + (StringUtils.isNotBlank(entityKey) ? "(" + entityKey + ")" : "");
+ return entitySetName + (entityKey == null || entityKey.isEmpty() ? "" : "(" + entityKey + ")");
}
public static String getEntityBasePath(final String entitySetName, final String entityKey) {
// expected singleton in case of null key
return entitySetName + File.separatorChar
- + (StringUtils.isNotBlank(entityKey) ? getEntityKey(entityKey) + File.separatorChar : "");
+ + (entityKey == null || entityKey.isEmpty() ? "" : getEntityKey(entityKey) + File.separatorChar);
}
public static String getLinksURI(final String entitySetName, final String entityId, final String linkName)
@@ -138,7 +130,7 @@ public abstract class Commons {
public static String getLinksPath(final String basePath, final String linkName, final Accept accept)
throws IOException {
try {
- return FSManager.instance(ODataServiceVersion.V40)
+ return FSManager.instance()
.getAbsolutePath(basePath + Constants.get(ConstantKey.LINKS_FILE_PATH)
+ File.separatorChar + linkName, accept);
} catch (Exception e) {
@@ -281,7 +273,7 @@ public abstract class Commons {
public static String getETag(final String basePath) throws Exception {
try {
- final InputStream is = FSManager.instance(ODataServiceVersion.V40).readFile(basePath + "etag", Accept.TEXT);
+ final InputStream is = FSManager.instance().readFile(basePath + "etag", Accept.TEXT);
if (is.available() <= 0) {
return null;
} else {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/utils/ConstantKey.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/ConstantKey.java b/fit/src/main/java/org/apache/olingo/fit/utils/ConstantKey.java
index 7315652..a8425df 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/ConstantKey.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/ConstantKey.java
@@ -25,20 +25,13 @@ public enum ConstantKey {
ODATA_COUNT_NAME,
ODATA_METADATA_PREFIX,
ODATA_METADATA_ENTITY_SUFFIX,
- ATOM_DEF_TYPE,
ATOM_PROPERTY_PREFIX,
- ATOM_METADATA_PREFIX,
- ATOM_METADATA_NS,
- ATOM_DATASERVICE_NS,
ATOM_LINK_ENTRY,
ATOM_LINK_FEED,
ATOM_LINK_REL,
- TYPE,
INLINE_LOCAL,
- INLINE_FILE_PATH,
LINKS_FILE_PATH,
INLINE,
- CONTENT,
PROPERTIES,
LINK,
DATASERVICES_NS,
@@ -66,6 +59,5 @@ public enum ConstantKey {
JSON_TYPE_SUFFIX,
JSON_ID_NAME,
JSON_EDITLINK_NAME,
- XHTTP_HEADER_NAME;
-
+ XHTTP_HEADER_NAME
};
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/utils/Constants.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/Constants.java b/fit/src/main/java/org/apache/olingo/fit/utils/Constants.java
index d0915a4..6a1d16a 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/Constants.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/Constants.java
@@ -55,19 +55,12 @@ public class Constants {
"http://localhost:9080/stub/StaticService/V40/Static.svc/$metadata#");
constants.put(ConstantKey.ODATA_METADATA_ENTITY_SUFFIX, "/$entity");
constants.put(ConstantKey.ODATA_COUNT_NAME, "odata.count");
- constants.put(ConstantKey.ATOM_DEF_TYPE, "Edm.String");
constants.put(ConstantKey.ATOM_PROPERTY_PREFIX, "d:");
- constants.put(ConstantKey.ATOM_METADATA_PREFIX, "m:");
- constants.put(ConstantKey.ATOM_METADATA_NS, "xmlns:m");
- constants.put(ConstantKey.ATOM_DATASERVICE_NS, "xmlns:d");
constants.put(ConstantKey.ATOM_LINK_ENTRY, "application/atom+xml;type=entry");
constants.put(ConstantKey.ATOM_LINK_FEED, "application/atom+xml;type=feed");
- constants.put(ConstantKey.TYPE, "m:type");
constants.put(ConstantKey.INLINE_LOCAL, "inline");
- constants.put(ConstantKey.INLINE_FILE_PATH, "inline");
constants.put(ConstantKey.LINKS_FILE_PATH, "links");
constants.put(ConstantKey.INLINE, "m:inline");
- constants.put(ConstantKey.CONTENT, "content");
constants.put(ConstantKey.PROPERTIES, "m:properties");
constants.put(ConstantKey.LINK, "link");
constants.put(ConstantKey.METADATA, "metadata");
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/utils/FSManager.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/FSManager.java b/fit/src/main/java/org/apache/olingo/fit/utils/FSManager.java
index d3530c8..8202619 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/FSManager.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/FSManager.java
@@ -25,8 +25,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
-import java.util.EnumMap;
-import java.util.Map;
import javax.ws.rs.NotFoundException;
@@ -61,37 +59,34 @@ public class FSManager {
private final FileSystemManager fsManager;
- private static Map<ODataServiceVersion, FSManager> instance =
- new EnumMap<ODataServiceVersion, FSManager>(ODataServiceVersion.class);
+ private static FSManager instance = null;
- private final ODataServiceVersion version;
-
- public static FSManager instance(final ODataServiceVersion version) throws IOException {
- if (!instance.containsKey(version)) {
- instance.put(version, new FSManager(version));
+ public static FSManager instance() throws IOException {
+ if (instance == null) {
+ instance = new FSManager();
}
- return instance.get(version);
+ return instance;
}
- private FSManager(final ODataServiceVersion version) throws IOException {
- this.version = version;
+ private FSManager() throws IOException {
fsManager = VFS.getManager();
- final FileObject basePath = fsManager.resolveFile(RES_PREFIX + File.separatorChar + version.name());
+ final FileObject basePath =
+ fsManager.resolveFile(RES_PREFIX + File.separatorChar + ODataServiceVersion.V40.name());
final String absoluteBaseFolder = basePath.getURL().getPath();
for (FileObject fo : find(basePath, null)) {
if (fo.getType() == FileType.FILE
&& !fo.getName().getBaseName().contains("Metadata")
&& !fo.getName().getBaseName().contains("metadata")) {
- final String path = fo.getURL().getPath().replace(absoluteBaseFolder, "//" + version.name());
+ final String path = fo.getURL().getPath().replace(absoluteBaseFolder, "//" + ODataServiceVersion.V40.name());
putInMemory(fo.getContent().getInputStream(), path);
}
}
}
public String getAbsolutePath(final String relativePath, final Accept accept) {
- return File.separatorChar + version.name() + File.separatorChar + relativePath
+ return File.separatorChar + ODataServiceVersion.V40.name() + File.separatorChar + relativePath
+ (accept == null ? "" : accept.getExtension());
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/utils/InjectableSerializerProvider.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/InjectableSerializerProvider.java b/fit/src/main/java/org/apache/olingo/fit/utils/InjectableSerializerProvider.java
deleted file mode 100644
index 02ada09..0000000
--- a/fit/src/main/java/org/apache/olingo/fit/utils/InjectableSerializerProvider.java
+++ /dev/null
@@ -1,42 +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.fit.utils;
-
-import com.fasterxml.jackson.databind.SerializationConfig;
-import com.fasterxml.jackson.databind.SerializerProvider;
-import com.fasterxml.jackson.databind.ser.DefaultSerializerProvider;
-import com.fasterxml.jackson.databind.ser.SerializerFactory;
-
-public class InjectableSerializerProvider extends DefaultSerializerProvider {
-
- private static final long serialVersionUID = 3432260063063739646L;
-
- public InjectableSerializerProvider(
- final SerializerProvider src, final SerializationConfig config, final SerializerFactory factory) {
-
- super(src, config, factory);
- }
-
- @Override
- public InjectableSerializerProvider createInstance(
- final SerializationConfig config, final SerializerFactory factory) {
-
- return this;
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/utils/JSONUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/JSONUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/JSONUtilities.java
index 8be6b11..b18886d 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/JSONUtilities.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/JSONUtilities.java
@@ -39,7 +39,6 @@ import org.apache.olingo.fit.metadata.Metadata;
import org.apache.olingo.fit.metadata.NavigationProperty;
import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.databind.InjectableValues;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
@@ -48,21 +47,10 @@ import com.fasterxml.jackson.databind.node.TextNode;
public class JSONUtilities extends AbstractUtilities {
- private final ObjectMapper mapper;
+ private final ObjectMapper mapper = new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL);
public JSONUtilities(final Metadata metadata) throws IOException {
super(metadata);
-
- mapper = new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL);
- mapper.setInjectableValues(new InjectableValues.Std().
- addValue(Boolean.class, Boolean.TRUE));
- // addValue(ODataServiceVersion.class, version))
-
- mapper.setSerializerProvider(new InjectableSerializerProvider(mapper.getSerializerProvider(),
- mapper.getSerializationConfig().
- // withAttribute(ODataServiceVersion.class, version).
- withAttribute(Boolean.class, Boolean.TRUE),
- mapper.getSerializerFactory()));
}
@Override
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/utils/MetadataLinkInfo.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/MetadataLinkInfo.java b/fit/src/main/java/org/apache/olingo/fit/utils/MetadataLinkInfo.java
deleted file mode 100644
index e79ce96..0000000
--- a/fit/src/main/java/org/apache/olingo/fit/utils/MetadataLinkInfo.java
+++ /dev/null
@@ -1,182 +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.fit.utils;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import javax.ws.rs.NotFoundException;
-
-public class MetadataLinkInfo {
-
- private Map<String, EntitySet> entitySets = new HashMap<String, EntitySet>();
-
- public void setSingleton(final String entitySetName) {
- entitySets.get(entitySetName).setSingleton(true);
- }
-
- public boolean isSingleton(final String entitySetName) {
- return entitySets.get(entitySetName).isSingleton();
- }
-
- public Set<String> getEntitySets() {
- return entitySets.keySet();
- }
-
- public void addEntitySet(final String entitySetName) {
- if (!entitySets.containsKey(entitySetName)) {
- entitySets.put(entitySetName, new EntitySet(entitySetName));
- }
- }
-
- public void addLink(
- final String entitySetName, final String linkName, final String targetName, final boolean isFeed) {
- final EntitySet entitySet;
- if (entitySets.containsKey(entitySetName)) {
- entitySet = entitySets.get(entitySetName);
- } else {
- entitySet = new EntitySet(entitySetName);
- entitySets.put(entitySetName, entitySet);
- }
-
- entitySet.add(linkName, targetName, isFeed);
- }
-
- public Set<String> getNavigationLinkNames(final String entitySetName) {
- final Set<String> res = new HashSet<String>();
-
- if (!entitySets.containsKey(entitySetName)) {
- throw new NotFoundException();
- }
-
- for (NavigationLink navigationLink : entitySets.get(entitySetName).getLinks()) {
- res.add(navigationLink.getName());
- }
-
- return res;
- }
-
- public boolean exists(final String entitySetName, final String linkName) {
- try {
- return getNavigationLinkNames(entitySetName).contains(linkName);
- } catch (Exception e) {
- return false;
- }
- }
-
- public boolean isFeed(final String entitySetName, final String linkName) {
- return entitySets.containsKey(entitySetName) && entitySets.get(entitySetName).isFeed(linkName);
- }
-
- public String getTargetName(final String entitySetName, final String linkName) {
- if (!entitySets.containsKey(entitySetName)) {
- throw new NotFoundException();
- }
-
- final String targetName = entitySets.get(entitySetName).getLink(linkName).getTargetName();
- return targetName.substring(targetName.lastIndexOf(".") + 1);
- }
-
- private static class EntitySet {
-
- private String name;
-
- private Set<NavigationLink> links;
-
- private boolean singleton;
-
- public EntitySet(final String name) {
- this.name = name;
- links = new HashSet<NavigationLink>();
- }
-
- public void add(final String linkName, final String targetName, final boolean isFeed) {
- links.add(new NavigationLink(linkName, targetName, isFeed));
- }
-
- public Set<NavigationLink> getLinks() {
- return links;
- }
-
- public NavigationLink getLink(final String linkName) {
- for (NavigationLink navigationLink : links) {
- if (linkName.equalsIgnoreCase(navigationLink.getName())) {
- return navigationLink;
- }
- }
-
- throw new NotFoundException();
- }
-
- public boolean isFeed(final String linkName) {
- try {
- return getLink(linkName).isFeed();
- } catch (Exception e) {
- return false;
- }
- }
-
- public boolean isSingleton() {
- return singleton;
- }
-
- public void setSingleton(final boolean singleton) {
- this.singleton = singleton;
- }
-
- @Override
- public String toString() {
- return name + ": " + links;
- }
- }
-
- private static class NavigationLink {
-
- private final String name;
-
- private final String targetName;
-
- private final boolean feed;
-
- public NavigationLink(final String name, final String targetName, final boolean feed) {
- this.name = name;
- this.targetName = targetName;
- this.feed = feed;
- }
-
- public String getName() {
- return name;
- }
-
- public String getTargetName() {
- return targetName;
- }
-
- public boolean isFeed() {
- return feed;
- }
-
- @Override
- public String toString() {
- return name + "(feed: " + isFeed() + ")";
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/utils/XMLUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/XMLUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/XMLUtilities.java
index 1078e2f..c7930f0 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/XMLUtilities.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/XMLUtilities.java
@@ -38,6 +38,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.regex.Pattern;
import javax.ws.rs.NotFoundException;
import javax.xml.namespace.QName;
@@ -61,6 +62,8 @@ import org.apache.olingo.fit.metadata.NavigationProperty;
public class XMLUtilities extends AbstractUtilities {
+ private static final Pattern ENTITY_URI_PATTERN = Pattern.compile(".*\\/.*\\(.*\\)");
+
protected static XMLInputFactory ifactory = null;
protected static XMLOutputFactory ofactory = null;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/Customer.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/Customer.java b/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/Customer.java
index 405ce0a..b9d15cc 100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/Customer.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/Customer.java
@@ -18,9 +18,7 @@
*/
package org.apache.olingo.fit.proxy.demo.odatademo.types;
-// CHECKSTYLE:OFF (Maven checkstyle)
import java.util.concurrent.Future;
-// CHECKSTYLE:ON (Maven checkstyle)
import org.apache.olingo.ext.proxy.api.annotations.Key;
@@ -30,9 +28,7 @@ import org.apache.olingo.ext.proxy.api.annotations.Key;
hasStream = false,
isAbstract = false,
baseType = "ODataDemo.Person")
-public interface Customer
- extends org.apache.olingo.ext.proxy.api.Annotatable,
- Person {
+public interface Customer extends Person {
@Override
Customer load();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/Employee.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/Employee.java b/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/Employee.java
index 4b55f53..8b48599 100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/Employee.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/Employee.java
@@ -18,9 +18,7 @@
*/
package org.apache.olingo.fit.proxy.demo.odatademo.types;
-// CHECKSTYLE:OFF (Maven checkstyle)
import java.util.concurrent.Future;
-// CHECKSTYLE:ON (Maven checkstyle)
import org.apache.olingo.ext.proxy.api.annotations.Key;
@@ -30,9 +28,7 @@ import org.apache.olingo.ext.proxy.api.annotations.Key;
hasStream = false,
isAbstract = false,
baseType = "ODataDemo.Person")
-public interface Employee
- extends org.apache.olingo.ext.proxy.api.Annotatable,
- Person {
+public interface Employee extends Person {
@Override
Employee load();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/FeaturedProduct.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/FeaturedProduct.java b/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/FeaturedProduct.java
index 0d09511..b38852c 100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/FeaturedProduct.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/FeaturedProduct.java
@@ -18,9 +18,7 @@
*/
package org.apache.olingo.fit.proxy.demo.odatademo.types;
-// CHECKSTYLE:OFF (Maven checkstyle)
import java.util.concurrent.Future;
-// CHECKSTYLE:ON (Maven checkstyle)
import org.apache.olingo.ext.proxy.api.annotations.Key;
@@ -30,9 +28,7 @@ import org.apache.olingo.ext.proxy.api.annotations.Key;
hasStream = false,
isAbstract = false,
baseType = "ODataDemo.Product")
-public interface FeaturedProduct
- extends org.apache.olingo.ext.proxy.api.Annotatable,
- Product {
+public interface FeaturedProduct extends Product {
@Override
FeaturedProduct load();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/test/java/org/apache/olingo/fit/proxy/opentype/microsoft/test/odata/services/opentypesservice/types/IndexedRow.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/opentype/microsoft/test/odata/services/opentypesservice/types/IndexedRow.java b/fit/src/test/java/org/apache/olingo/fit/proxy/opentype/microsoft/test/odata/services/opentypesservice/types/IndexedRow.java
index 2de8869..f2618f2 100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/opentype/microsoft/test/odata/services/opentypesservice/types/IndexedRow.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/opentype/microsoft/test/odata/services/opentypesservice/types/IndexedRow.java
@@ -18,11 +18,8 @@
*/
package org.apache.olingo.fit.proxy.opentype.microsoft.test.odata.services.opentypesservice.types;
-// CHECKSTYLE:OFF (Maven checkstyle)
import java.util.concurrent.Future;
-// CHECKSTYLE:ON (Maven checkstyle)
-import org.apache.olingo.ext.proxy.api.AbstractOpenType;
import org.apache.olingo.ext.proxy.api.annotations.Key;
@org.apache.olingo.ext.proxy.api.annotations.Namespace("Microsoft.Test.OData.Services.OpenTypesServiceV4")
@@ -31,10 +28,7 @@ import org.apache.olingo.ext.proxy.api.annotations.Key;
hasStream = false,
isAbstract = false,
baseType = "Microsoft.Test.OData.Services.OpenTypesServiceV4.Row")
-public interface IndexedRow
- extends org.apache.olingo.ext.proxy.api.Annotatable,
- Row,
- AbstractOpenType {
+public interface IndexedRow extends Row {
@Override
IndexedRow load();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/CreditCardPI.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/CreditCardPI.java b/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/CreditCardPI.java
index 6873492..179f2e1 100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/CreditCardPI.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/CreditCardPI.java
@@ -18,9 +18,7 @@
*/
package org.apache.olingo.fit.proxy.staticservice.microsoft.test.odata.services.odatawcfservice.types;
-// CHECKSTYLE:OFF (Maven checkstyle)
import java.util.concurrent.Future;
-// CHECKSTYLE:ON (Maven checkstyle)
import org.apache.olingo.ext.proxy.api.AbstractEntitySet;
import org.apache.olingo.ext.proxy.api.annotations.Key;
@@ -31,9 +29,7 @@ import org.apache.olingo.ext.proxy.api.annotations.Key;
hasStream = false,
isAbstract = false,
baseType = "Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument")
-public interface CreditCardPI
- extends org.apache.olingo.ext.proxy.api.Annotatable,
- PaymentInstrument {
+public interface CreditCardPI extends PaymentInstrument {
@Override
CreditCardPI load();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/Customer.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/Customer.java b/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/Customer.java
index ed6fdc1..af66869 100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/Customer.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/Customer.java
@@ -18,9 +18,7 @@
*/
package org.apache.olingo.fit.proxy.staticservice.microsoft.test.odata.services.odatawcfservice.types;
-// CHECKSTYLE:OFF (Maven checkstyle)
import java.util.concurrent.Future;
-// CHECKSTYLE:ON (Maven checkstyle)
import org.apache.olingo.ext.proxy.api.annotations.Key;
@@ -30,9 +28,7 @@ import org.apache.olingo.ext.proxy.api.annotations.Key;
hasStream = false,
isAbstract = false,
baseType = "Microsoft.Test.OData.Services.ODataWCFService.Person")
-public interface Customer
- extends org.apache.olingo.ext.proxy.api.Annotatable,
- Person {
+public interface Customer extends Person {
@Override
Customer load();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/Employee.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/Employee.java b/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/Employee.java
index f33ccb3..f0b4e80 100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/Employee.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/Employee.java
@@ -18,9 +18,7 @@
*/
package org.apache.olingo.fit.proxy.staticservice.microsoft.test.odata.services.odatawcfservice.types;
-// CHECKSTYLE:OFF (Maven checkstyle)
import java.util.concurrent.Future;
-// CHECKSTYLE:ON (Maven checkstyle)
import org.apache.olingo.ext.proxy.api.annotations.Key;
@@ -30,9 +28,7 @@ import org.apache.olingo.ext.proxy.api.annotations.Key;
hasStream = false,
isAbstract = false,
baseType = "Microsoft.Test.OData.Services.ODataWCFService.Person")
-public interface Employee
- extends org.apache.olingo.ext.proxy.api.Annotatable,
- Person {
+public interface Employee extends Person {
@Override
Employee load();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/PublicCompany.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/PublicCompany.java b/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/PublicCompany.java
index cdace92..40144ef 100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/PublicCompany.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/PublicCompany.java
@@ -18,12 +18,9 @@
*/
package org.apache.olingo.fit.proxy.staticservice.microsoft.test.odata.services.odatawcfservice.types;
-// CHECKSTYLE:OFF (Maven checkstyle)
import java.util.concurrent.Future;
-// CHECKSTYLE:ON (Maven checkstyle)
import org.apache.olingo.ext.proxy.api.AbstractEntitySet;
-import org.apache.olingo.ext.proxy.api.AbstractOpenType;
import org.apache.olingo.ext.proxy.api.annotations.Key;
@org.apache.olingo.ext.proxy.api.annotations.Namespace("Microsoft.Test.OData.Services.ODataWCFService")
@@ -32,10 +29,7 @@ import org.apache.olingo.ext.proxy.api.annotations.Key;
hasStream = false,
isAbstract = false,
baseType = "Microsoft.Test.OData.Services.ODataWCFService.Company")
-public interface PublicCompany
- extends org.apache.olingo.ext.proxy.api.Annotatable,
- Company,
- AbstractOpenType {
+public interface PublicCompany extends Company {
@Override
PublicCompany load();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/EntityReferencesITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/EntityReferencesITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/EntityReferencesITCase.java
index 94867af..bac2927 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/EntityReferencesITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/EntityReferencesITCase.java
@@ -24,6 +24,7 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import java.net.URI;
+import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -553,11 +554,11 @@ public class EntityReferencesITCase extends AbstractParamTecSvcITCase {
.getReferenceSingleChangeRequest(new URI(SERVICE_URI), uri, reference)
.execute();
assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode());
-
+
final String cookie = response.getHeader(HttpHeader.SET_COOKIE).iterator().next();
- Map<QueryOption, Object> expandOptions = new HashMap<QueryOption, Object>();
+ Map<QueryOption, Object> expandOptions = new EnumMap<QueryOption, Object>(QueryOption.class);
expandOptions.put(QueryOption.EXPAND, NAV_PROPERTY_ET_KEY_NAV_ONE);
-
+
final URI getURI = getClient().newURIBuilder(SERVICE_URI)
.appendEntitySetSegment(ES_TWO_KEY_NAV)
.appendKeySegment(esTwoKeyNavKey)
@@ -601,12 +602,12 @@ public class EntityReferencesITCase extends AbstractParamTecSvcITCase {
.getReferenceAddingRequest(new URI(SERVICE_URI), uri, reference)
.execute();
assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode());
-
+
final String cookie = response.getHeader(HttpHeader.SET_COOKIE).iterator().next();
- final Map<QueryOption, Object> expandOptions = new HashMap<QueryOption, Object>();
+ final Map<QueryOption, Object> expandOptions = new EnumMap<QueryOption, Object>(QueryOption.class);
expandOptions.put(QueryOption.EXPAND, NAV_PROPERTY_ET_KEY_NAV_MANY);
expandOptions.put(QueryOption.FILTER, "PropertyInt16 eq 1");
-
+
final URI getURI = getClient().newURIBuilder(SERVICE_URI)
.appendEntitySetSegment(ES_TWO_KEY_NAV)
.appendKeySegment(esTwoKeyNavKey)
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java
index 507b9a9..0f3743b 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java
@@ -23,6 +23,8 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import java.net.URI;
+import java.util.Collections;
+import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -49,11 +51,10 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
@Test
public void filter() {
- Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
- options.put(QueryOption.FILTER, "PropertyString eq '2'");
-
final ODataRetrieveResponse<ClientEntitySet> response =
- buildRequest(ES_TWO_KEY_NAV, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, options);
+ buildRequest(ES_TWO_KEY_NAV, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY,
+ Collections.singletonMap(QueryOption.FILTER, (Object) "PropertyString eq '2'"));
+
final List<ClientEntity> entities = response.getBody().getEntities();
assertEquals(4, entities.size());
@@ -87,11 +88,9 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
@Test
public void orderBy() {
- Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
- options.put(QueryOption.ORDERBY, "PropertyString desc");
-
final ODataRetrieveResponse<ClientEntitySet> response =
- buildRequest(ES_TWO_KEY_NAV, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, options);
+ buildRequest(ES_TWO_KEY_NAV, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY,
+ Collections.<QueryOption, Object> singletonMap(QueryOption.ORDERBY, "PropertyString desc"));
final List<ClientEntity> entities = response.getBody().getEntities();
assertEquals(4, entities.size());
@@ -117,11 +116,9 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
@Test
public void skip() {
- Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
- options.put(QueryOption.SKIP, "1");
-
final ODataRetrieveResponse<ClientEntitySet> response =
- buildRequest(ES_KEY_NAV, NAV_PROPERTY_ET_KEY_NAV_MANY, options);
+ buildRequest(ES_KEY_NAV, NAV_PROPERTY_ET_KEY_NAV_MANY,
+ Collections.singletonMap(QueryOption.SKIP, (Object) "1"));
final List<ClientEntity> entities = response.getBody().getEntities();
assertEquals(3, entities.size());
@@ -148,11 +145,9 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
@Test
public void top() {
- Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
- options.put(QueryOption.TOP, "1");
-
final ODataRetrieveResponse<ClientEntitySet> response =
- buildRequest(ES_KEY_NAV, NAV_PROPERTY_ET_KEY_NAV_MANY, options);
+ buildRequest(ES_KEY_NAV, NAV_PROPERTY_ET_KEY_NAV_MANY,
+ Collections.<QueryOption, Object> singletonMap(QueryOption.TOP, "1"));
final List<ClientEntity> entities = response.getBody().getEntities();
assertEquals(3, entities.size());
@@ -179,7 +174,7 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
@Test
public void combinedSystemQueryOptions() {
- Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
+ Map<QueryOption, Object> options = new EnumMap<QueryOption, Object>(QueryOption.class);
options.put(QueryOption.SELECT, "PropertyInt16,PropertyString");
options.put(QueryOption.FILTER, "PropertyInt16 eq 1");
options.put(QueryOption.SKIP, "1");
@@ -217,7 +212,7 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
@Ignore("Server do not support navigation property count annotations")
public void count() {
final ODataClient client = getEdmEnabledClient();
- Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
+ Map<QueryOption, Object> options = new EnumMap<QueryOption, Object>(QueryOption.class);
options.put(QueryOption.SELECT, "PropertyInt16");
options.put(QueryOption.COUNT, true);
@@ -255,14 +250,14 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
public void singleEntityWithExpand() {
/* A single entity request will be dispatched to a different processor method than entity set request */
final ODataClient client = getEdmEnabledClient();
- Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
- options.put(QueryOption.FILTER, "PropertyInt16 lt 2");
Map<String, Object> keys = new HashMap<String, Object>();
keys.put("PropertyInt16", 1);
keys.put("PropertyString", "1");
final URI uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_TWO_KEY_NAV).appendKeySegment(keys)
- .expandWithOptions(NAV_PROPERTY_ET_KEY_NAV_MANY, options).build();
+ .expandWithOptions(NAV_PROPERTY_ET_KEY_NAV_MANY,
+ Collections.singletonMap(QueryOption.FILTER, (Object) "PropertyInt16 lt 2"))
+ .build();
final ODataRetrieveResponse<ClientEntity> response =
client.getRetrieveRequestFactory().getEntityRequest(uri).execute();
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
@@ -275,11 +270,12 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
@Test
public void URIEscaping() {
- Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
- options.put(QueryOption.FILTER, "PropertyInt16 eq 1"
- + " and PropertyComp/PropertyComp/PropertyDuration eq duration'PT1S' and length(PropertyString) gt 4");
final ODataRetrieveResponse<ClientEntitySet> response =
- buildRequest(ES_TWO_KEY_NAV, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, options);
+ buildRequest(ES_TWO_KEY_NAV, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY,
+ Collections.<QueryOption, Object> singletonMap(QueryOption.FILTER,
+ "PropertyInt16 eq 1"
+ + " and PropertyComp/PropertyComp/PropertyDuration eq duration'PT1S'"
+ + " and length(PropertyString) gt 4"));
final List<ClientEntity> entities = response.getBody().getEntities();
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
@@ -296,7 +292,7 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
// Define filters to select explicit the entities at any level => Circle
final ODataClient client = getEdmEnabledClient();
- Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
+ Map<QueryOption, Object> options = new EnumMap<QueryOption, Object>(QueryOption.class);
options.put(QueryOption.EXPAND, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY
+ "($expand=" + NAV_PROPERTY_ET_TWO_KEY_NAV_MANY
+ "($expand=" + NAV_PROPERTY_ET_TWO_KEY_NAV_MANY + "))");
@@ -371,7 +367,7 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
@Test
public void systemQueryOptionOnThirdLevel() {
final ODataClient client = getEdmEnabledClient();
- Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
+ Map<QueryOption, Object> options = new EnumMap<QueryOption, Object>(QueryOption.class);
options.put(QueryOption.EXPAND, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY
+ "($expand=" + NAV_PROPERTY_ET_TWO_KEY_NAV_MANY
+ "($expand=" + NAV_PROPERTY_ET_TWO_KEY_NAV_MANY
@@ -444,7 +440,7 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
@Test
public void expandWithSearchQuery() {
final ODataClient client = getEdmEnabledClient();
- Map<QueryOption, Object> expandOptions = new HashMap<QueryOption, Object>();
+ Map<QueryOption, Object> expandOptions = new EnumMap<QueryOption, Object>(QueryOption.class);
expandOptions.put(QueryOption.SEARCH, "abc");
expandOptions.put(QueryOption.FILTER, "PropertyInt16 eq 1");
@@ -464,12 +460,10 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
@Test
public void expandWithLevels() {
final ODataClient client = getEdmEnabledClient();
- Map<QueryOption, Object> expandOptions = new HashMap<QueryOption, Object>();
- expandOptions.put(QueryOption.LEVELS, 2);
// expand=*($levels=2)
URI uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV)
- .expandWithOptions("*", expandOptions)
+ .expandWithOptions("*", Collections.<QueryOption, Object> singletonMap(QueryOption.LEVELS, 2))
.build();
try {
@@ -479,10 +473,9 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
}
// expand=NavPropertyETTwoKeyNavMany($levels=2)
- expandOptions.clear();
- expandOptions.put(QueryOption.LEVELS, 2);
uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV)
- .expandWithOptions(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, expandOptions)
+ .expandWithOptions(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY,
+ Collections.<QueryOption, Object> singletonMap(QueryOption.LEVELS, 2))
.build();
try {
@@ -492,10 +485,10 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
}
// expand=NavPropertyETTwoKeyNavMany($expand=NavPropertyETTwoKeyNavMany($levels=2))
- expandOptions.clear();
- expandOptions.put(QueryOption.EXPAND, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY + "($levels=2)");
uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV)
- .expandWithOptions(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, expandOptions)
+ .expandWithOptions(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY,
+ Collections.<QueryOption, Object> singletonMap(QueryOption.EXPAND,
+ NAV_PROPERTY_ET_TWO_KEY_NAV_MANY + "($levels=2)"))
.build();
try {
@@ -505,10 +498,9 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
}
// expand=NavPropertyETTwoKeyNavMany($expand=NavPropertyETTwoKeyNavMany($levels=2);$levels=3)
- expandOptions.clear();
- expandOptions.put(QueryOption.LEVELS, 2);
uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV)
- .expandWithOptions(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, expandOptions)
+ .expandWithOptions(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY,
+ Collections.<QueryOption, Object> singletonMap(QueryOption.LEVELS, 2))
.build();
try {
@@ -518,7 +510,7 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
}
// expand=NavPropertyETTwoKeyNavMany($expand=NavPropertyETTwoKeyNavMany($levels=2))
- expandOptions.clear();
+ Map<QueryOption, Object> expandOptions = new EnumMap<QueryOption, Object>(QueryOption.class);
expandOptions.put(QueryOption.EXPAND, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY + "($levels=2)");
expandOptions.put(QueryOption.LEVELS, 3);
uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV)
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/AbstractClientEntitySet.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/AbstractClientEntitySet.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/AbstractClientEntitySet.java
deleted file mode 100644
index d59af93..0000000
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/AbstractClientEntitySet.java
+++ /dev/null
@@ -1,114 +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.core.domain;
-
-import java.net.URI;
-
-import org.apache.olingo.client.api.domain.AbstractClientPayload;
-import org.apache.olingo.client.api.domain.ClientEntitySet;
-
-public abstract class AbstractClientEntitySet extends AbstractClientPayload implements ClientEntitySet {
-
- /**
- * Link to the next page.
- */
- private URI next;
-
- /**
- * Number of ODataEntities contained in this entity set.
- * <br/>
- * If <tt>$count</tt> was requested, this value comes from there.
- */
- private Integer count;
-
- /**
- * Constructor.
- */
- public AbstractClientEntitySet() {
- super(null);
- }
-
- /**
- * Constructor.
- *
- * @param next next link.
- */
- public AbstractClientEntitySet(final URI next) {
- super(null);
- this.next = next;
- }
-
- @Override
- public URI getNext() {
- return next;
- }
-
- @Override
- public Integer getCount() {
- return count;
- }
-
- @Override
- public void setCount(final int count) {
- this.count = count;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = super.hashCode();
- result = prime * result + ((count == null) ? 0 : count.hashCode());
- result = prime * result + ((next == null) ? 0 : next.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof AbstractClientEntitySet)) {
- return false;
- }
- AbstractClientEntitySet other = (AbstractClientEntitySet) obj;
- if (count == null) {
- if (other.count != null) {
- return false;
- }
- } else if (!count.equals(other.count)) {
- return false;
- }
- if (next == null) {
- if (other.next != null) {
- return false;
- }
- } else if (!next.equals(other.next)) {
- return false;
- }
- return true;
- }
-
- @Override
- public String toString() {
- return "AbstractClientEntitySet [next=" + next + ", count=" + count + "super[" + super.toString() + "]]";
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientCollectionValueImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientCollectionValueImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientCollectionValueImpl.java
index c83fceb..2a3aebc 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientCollectionValueImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientCollectionValueImpl.java
@@ -29,7 +29,7 @@ import org.apache.olingo.client.api.domain.ClientEnumValue;
import org.apache.olingo.client.api.domain.ClientValue;
public class ClientCollectionValueImpl<OV extends ClientValue> extends AbstractClientValue
- implements ClientCollectionValue<OV>, ClientValue {
+ implements ClientCollectionValue<OV> {
/**
* Constructor.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientEntitySetImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientEntitySetImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientEntitySetImpl.java
index 29ede4c..21e13b4 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientEntitySetImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientEntitySetImpl.java
@@ -22,11 +22,24 @@ import java.net.URI;
import java.util.ArrayList;
import java.util.List;
+import org.apache.olingo.client.api.domain.AbstractClientPayload;
import org.apache.olingo.client.api.domain.ClientAnnotation;
import org.apache.olingo.client.api.domain.ClientEntity;
import org.apache.olingo.client.api.domain.ClientEntitySet;
-public class ClientEntitySetImpl extends AbstractClientEntitySet implements ClientEntitySet {
+public class ClientEntitySetImpl extends AbstractClientPayload implements ClientEntitySet {
+
+ /**
+ * Link to the next page.
+ */
+ private final URI next;
+
+ /**
+ * Number of ODataEntities contained in this entity set.
+ * <br/>
+ * If <tt>$count</tt> was requested, this value comes from there.
+ */
+ private Integer count;
private URI deltaLink;
@@ -35,11 +48,28 @@ public class ClientEntitySetImpl extends AbstractClientEntitySet implements Clie
private final List<ClientAnnotation> annotations = new ArrayList<ClientAnnotation>();
public ClientEntitySetImpl() {
- super();
+ super(null);
+ next = null;
}
public ClientEntitySetImpl(final URI next) {
- super(next);
+ super(null);
+ this.next = next;
+ }
+
+ @Override
+ public URI getNext() {
+ return next;
+ }
+
+ @Override
+ public Integer getCount() {
+ return count;
+ }
+
+ @Override
+ public void setCount(final int count) {
+ this.count = count;
}
@Override
@@ -66,6 +96,8 @@ public class ClientEntitySetImpl extends AbstractClientEntitySet implements Clie
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
+ result = prime * result + ((count == null) ? 0 : count.hashCode());
+ result = prime * result + ((next == null) ? 0 : next.hashCode());
result = prime * result + ((annotations == null) ? 0 : annotations.hashCode());
result = prime * result + ((deltaLink == null) ? 0 : deltaLink.hashCode());
result = prime * result + ((entities == null) ? 0 : entities.hashCode());
@@ -77,40 +109,20 @@ public class ClientEntitySetImpl extends AbstractClientEntitySet implements Clie
if (this == obj) {
return true;
}
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof ClientEntitySetImpl)) {
- return false;
- }
- ClientEntitySetImpl other = (ClientEntitySetImpl) obj;
- if (annotations == null) {
- if (other.annotations != null) {
- return false;
- }
- } else if (!annotations.equals(other.annotations)) {
- return false;
- }
- if (deltaLink == null) {
- if (other.deltaLink != null) {
- return false;
- }
- } else if (!deltaLink.equals(other.deltaLink)) {
- return false;
- }
- if (entities == null) {
- if (other.entities != null) {
- return false;
- }
- } else if (!entities.equals(other.entities)) {
+ if (obj == null || !(obj instanceof ClientEntitySetImpl)) {
return false;
}
- return true;
+ final ClientEntitySetImpl other = (ClientEntitySetImpl) obj;
+ return (count == null ? other.count == null : count.equals(other.count))
+ && (next == null ? other.next == null : next.equals(other.next))
+ && annotations.equals(other.annotations)
+ && (deltaLink == null ? other.deltaLink == null : deltaLink.equals(other.deltaLink))
+ && entities.equals(other.entities);
}
@Override
public String toString() {
return "ClientEntitySetImpl [deltaLink=" + deltaLink + ", entities=" + entities + ", annotations=" + annotations
- + "super[" + super.toString() + "]]";
+ + ", next=" + next + ", count=" + count + "super[" + super.toString() + "]]";
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPrimitiveValueImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPrimitiveValueImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPrimitiveValueImpl.java
index cdfe623..4824632 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPrimitiveValueImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPrimitiveValueImpl.java
@@ -21,11 +21,10 @@ package org.apache.olingo.client.core.domain;
import java.math.BigDecimal;
import java.util.UUID;
-import org.apache.olingo.commons.api.Constants;
import org.apache.olingo.client.api.domain.AbstractClientValue;
import org.apache.olingo.client.api.domain.ClientEnumValue;
import org.apache.olingo.client.api.domain.ClientPrimitiveValue;
-import org.apache.olingo.client.api.domain.ClientValue;
+import org.apache.olingo.commons.api.Constants;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
@@ -33,7 +32,7 @@ import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
-public class ClientPrimitiveValueImpl extends AbstractClientValue implements ClientValue, ClientPrimitiveValue {
+public class ClientPrimitiveValueImpl extends AbstractClientValue implements ClientPrimitiveValue {
public static class BuilderImpl implements Builder {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPropertyImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPropertyImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPropertyImpl.java
index f78c506..8c8c3ee 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPropertyImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPropertyImpl.java
@@ -18,30 +18,21 @@
*/
package org.apache.olingo.client.core.domain;
-import org.apache.olingo.client.api.domain.ClientAnnotatable;
+import java.util.ArrayList;
+import java.util.List;
+
import org.apache.olingo.client.api.domain.ClientAnnotation;
-import org.apache.olingo.client.api.domain.ClientCollectionValue;
-import org.apache.olingo.client.api.domain.ClientComplexValue;
-import org.apache.olingo.client.api.domain.ClientEnumValue;
-import org.apache.olingo.client.api.domain.ClientPrimitiveValue;
import org.apache.olingo.client.api.domain.ClientProperty;
-import org.apache.olingo.client.api.domain.ClientValuable;
import org.apache.olingo.client.api.domain.ClientValue;
-import java.util.ArrayList;
-import java.util.List;
-
-public final class ClientPropertyImpl implements ClientProperty, ClientAnnotatable, ClientValuable {
+public final class ClientPropertyImpl extends ClientValuableImpl implements ClientProperty {
private final List<ClientAnnotation> annotations = new ArrayList<ClientAnnotation>();
private final String name;
- private final ClientValue value;
- private final ClientValuable valuable;
public ClientPropertyImpl(final String name, final ClientValue value) {
+ super(value);
this.name = name;
- this.value = value;
- this.valuable = new ClientValuableImpl(value);
}
/**
@@ -55,16 +46,6 @@ public final class ClientPropertyImpl implements ClientProperty, ClientAnnotatab
}
/**
- * Returns property value.
- *
- * @return property value.
- */
- @Override
- public ClientValue getValue() {
- return value;
- }
-
- /**
* Checks if has null value.
*
* @return 'TRUE' if has null value; 'FALSE' otherwise.
@@ -74,87 +55,18 @@ public final class ClientPropertyImpl implements ClientProperty, ClientAnnotatab
return value == null || value.isPrimitive() && value.asPrimitive().toValue() == null;
}
- /**
- * Checks if has primitive value.
- *
- * @return 'TRUE' if has primitive value; 'FALSE' otherwise.
- */
- @Override
- public boolean hasPrimitiveValue() {
- return !hasNullValue() && value.isPrimitive();
- }
-
- /**
- * Gets primitive value.
- *
- * @return primitive value if exists; null otherwise.
- */
- @Override
- public ClientPrimitiveValue getPrimitiveValue() {
- return hasPrimitiveValue() ? value.asPrimitive() : null;
- }
-
- /**
- * Checks if has complex value.
- *
- * @return 'TRUE' if has complex value; 'FALSE' otherwise.
- */
- @Override
- public boolean hasComplexValue() {
- return !hasNullValue() && value.isComplex();
- }
-
- /**
- * Checks if has collection value.
- *
- * @return 'TRUE' if has collection value; 'FALSE' otherwise.
- */
- @Override
- public boolean hasCollectionValue() {
- return !hasNullValue() && value.isCollection();
- }
-
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
- if (obj == null) {
- return false;
- }
- if (!(obj instanceof ClientPropertyImpl)) {
- return false;
- }
- ClientPropertyImpl other = (ClientPropertyImpl) obj;
- if (annotations == null) {
- if (other.annotations != null) {
- return false;
- }
- } else if (!annotations.equals(other.annotations)) {
- return false;
- }
- if (name == null) {
- if (other.name != null) {
- return false;
- }
- } else if (!name.equals(other.name)) {
- return false;
- }
- if (valuable == null) {
- if (other.valuable != null) {
- return false;
- }
- } else if (!valuable.equals(other.valuable)) {
+ if (obj == null || !(obj instanceof ClientPropertyImpl)) {
return false;
}
- if (value == null) {
- if (other.value != null) {
- return false;
- }
- } else if (!value.equals(other.value)) {
- return false;
- }
- return true;
+ final ClientPropertyImpl other = (ClientPropertyImpl) obj;
+ return annotations.equals(other.annotations)
+ && (name == null ? other.name == null : name.equals(other.name))
+ && (value == null ? other.value == null : value.equals(other.value));
}
@Override
@@ -163,42 +75,17 @@ public final class ClientPropertyImpl implements ClientProperty, ClientAnnotatab
int result = 1;
result = prime * result + ((annotations == null) ? 0 : annotations.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
- result = prime * result + ((valuable == null) ? 0 : valuable.hashCode());
result = prime * result + ((value == null) ? 0 : value.hashCode());
return result;
}
@Override
- public boolean hasEnumValue() {
- return valuable.hasEnumValue();
- }
-
- @Override
- public ClientEnumValue getEnumValue() {
- return valuable.getEnumValue();
- }
-
- @Override
- public ClientComplexValue getComplexValue() {
- return valuable.getComplexValue();
- }
-
- @Override
- public ClientCollectionValue<ClientValue> getCollectionValue() {
- return valuable.getCollectionValue();
- }
-
- @Override
public List<ClientAnnotation> getAnnotations() {
return annotations;
}
@Override
public String toString() {
- return "ODataPropertyImpl{"
- + "name=" + getName()
- + ",valuable=" + valuable
- + ", annotations=" + annotations
- + '}';
+ return "ClientPropertyImpl{" + "name=" + name + ", value=" + value + ", annotations=" + annotations + '}';
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientValuableImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientValuableImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientValuableImpl.java
index 4a032ce..4b94be6 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientValuableImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientValuableImpl.java
@@ -25,9 +25,9 @@ import org.apache.olingo.client.api.domain.ClientPrimitiveValue;
import org.apache.olingo.client.api.domain.ClientValuable;
import org.apache.olingo.client.api.domain.ClientValue;
-public final class ClientValuableImpl implements ClientValuable {
+public class ClientValuableImpl implements ClientValuable {
- private final ClientValue value;
+ protected final ClientValue value;
public ClientValuableImpl(final ClientValue value) {
this.value = value;
@@ -60,9 +60,7 @@ public final class ClientValuableImpl implements ClientValuable {
@Override
public ClientCollectionValue<ClientValue> getCollectionValue() {
- return hasCollectionValue()
- ? getValue().<ClientValue> asCollection()
- : null;
+ return hasCollectionValue() ? getValue().<ClientValue> asCollection() : null;
}
@Override
@@ -72,9 +70,7 @@ public final class ClientValuableImpl implements ClientValuable {
@Override
public ClientComplexValue getComplexValue() {
- return hasComplexValue()
- ? getValue().asComplex()
- : null;
+ return hasComplexValue() ? getValue().asComplex() : null;
}
@Override
@@ -84,9 +80,7 @@ public final class ClientValuableImpl implements ClientValuable {
@Override
public ClientEnumValue getEnumValue() {
- return hasEnumValue()
- ? getValue().asEnum()
- : null;
+ return hasEnumValue() ? getValue().asEnum() : null;
}
@Override
@@ -99,9 +93,7 @@ public final class ClientValuableImpl implements ClientValuable {
}
ClientValuableImpl that = (ClientValuableImpl) o;
-
return !(value != null ? !value.equals(that.value) : that.value != null);
-
}
@Override
@@ -111,8 +103,6 @@ public final class ClientValuableImpl implements ClientValuable {
@Override
public String toString() {
- return "ClientValuableImpl{" +
- "value=" + value +
- '}';
+ return "ClientValuableImpl{" + "value=" + value + '}';
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java
index 33144ec..f9f29e7 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java
@@ -714,7 +714,7 @@ public class ODataBinderImpl implements ODataBinder {
if (propertyType == null || propertyType.equals(EdmPrimitiveTypeKind.String.getFullQualifiedName().toString())) {
typeInfo = new EdmTypeInfo.Builder().setTypeExpression(typeName.toString()).build();
} else if(isPrimiteveType(typeName)) {
- // Inheritance is not allowed for primitve types, so we use the type given by the EDM
+ // Inheritance is not allowed for primitive types, so we use the type given by the EDM.
typeInfo = new EdmTypeInfo.Builder().setTypeExpression(typeName.toString()).build();
} else {
typeInfo = new EdmTypeInfo.Builder().setTypeExpression(propertyType).build();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/test/java/org/apache/olingo/client/core/AbstractTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/AbstractTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/AbstractTest.java
index bc116a8..d03b6d9 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/AbstractTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/AbstractTest.java
@@ -25,9 +25,7 @@ import org.junit.BeforeClass;
public abstract class AbstractTest {
- protected static ODataClient v4Client;
-
- protected abstract ODataClient getClient();
+ protected static final ODataClient client = ODataClientFactory.getClient();
@BeforeClass
public static void setUp() {
@@ -38,11 +36,6 @@ public abstract class AbstractTest {
XMLUnit.setCompareUnmatched(false);
}
- @BeforeClass
- public static void setClientInstances() {
- v4Client = ODataClientFactory.getClient();
- }
-
protected String getSuffix(final ContentType contentType) {
return contentType.isCompatible(ContentType.APPLICATION_ATOM_SVC)
|| contentType.isCompatible(ContentType.APPLICATION_ATOM_XML)
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/test/java/org/apache/olingo/client/core/AtomTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/AtomTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/AtomTest.java
index 9d5346b..ba20144 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/AtomTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/AtomTest.java
@@ -30,18 +30,12 @@ import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.apache.commons.io.IOUtils;
-import org.apache.olingo.client.api.ODataClient;
import org.apache.olingo.commons.api.format.ContentType;
import org.custommonkey.xmlunit.Diff;
public class AtomTest extends JSONTest {
@Override
- protected ODataClient getClient() {
- return v4Client;
- }
-
- @Override
protected ContentType getODataPubFormat() {
return ContentType.APPLICATION_ATOM_XML;
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/test/java/org/apache/olingo/client/core/EntitySetTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/EntitySetTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/EntitySetTest.java
index 199cd05..254e83f 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/EntitySetTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/EntitySetTest.java
@@ -26,7 +26,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
-import org.apache.olingo.client.api.ODataClient;
import org.apache.olingo.client.api.data.ResWrap;
import org.apache.olingo.client.api.domain.ClientEntity;
import org.apache.olingo.client.api.domain.ClientEntitySet;
@@ -37,23 +36,18 @@ import org.junit.Test;
public class EntitySetTest extends AbstractTest {
- @Override
- protected ODataClient getClient() {
- return v4Client;
- }
-
private void read(final ContentType contentType) throws IOException, ODataDeserializerException {
final InputStream input = getClass().getResourceAsStream("Customers." + getSuffix(contentType));
- final ClientEntitySet entitySet = getClient().getBinder().getODataEntitySet(
- getClient().getDeserializer(contentType).toEntitySet(input));
+ final ClientEntitySet entitySet = client.getBinder().getODataEntitySet(
+ client.getDeserializer(contentType).toEntitySet(input));
assertNotNull(entitySet);
assertEquals(2, entitySet.getEntities().size());
assertNull(entitySet.getNext());
final ClientEntitySet written =
- getClient().getBinder().getODataEntitySet(new ResWrap<EntityCollection>((URI) null, null,
- getClient().getBinder().getEntitySet(entitySet)));
+ client.getBinder().getODataEntitySet(new ResWrap<EntityCollection>((URI) null, null,
+ client.getBinder().getEntitySet(entitySet)));
assertEquals(entitySet, written);
}
@@ -69,8 +63,8 @@ public class EntitySetTest extends AbstractTest {
private void ref(final ContentType contentType) throws ODataDeserializerException {
final InputStream input = getClass().getResourceAsStream("collectionOfEntityReferences." + getSuffix(contentType));
- final ClientEntitySet entitySet = getClient().getBinder().getODataEntitySet(
- getClient().getDeserializer(contentType).toEntitySet(input));
+ final ClientEntitySet entitySet = client.getBinder().getODataEntitySet(
+ client.getDeserializer(contentType).toEntitySet(input));
assertNotNull(entitySet);
for (ClientEntity entity : entitySet.getEntities()) {
@@ -79,8 +73,8 @@ public class EntitySetTest extends AbstractTest {
entitySet.setCount(entitySet.getEntities().size());
final ClientEntitySet written =
- getClient().getBinder().getODataEntitySet(new ResWrap<EntityCollection>((URI) null, null,
- getClient().getBinder().getEntitySet(entitySet)));
+ client.getBinder().getODataEntitySet(new ResWrap<EntityCollection>((URI) null, null,
+ client.getBinder().getEntitySet(entitySet)));
assertEquals(entitySet, written);
}
[13/22] olingo-odata4 git commit: OLINGO-861, OLINGO-863, OLINGO-868,
OLINGO-869 : Improvements to MetadataParser for annotation support
Posted by mi...@apache.org.
OLINGO-861, OLINGO-863, OLINGO-868, OLINGO-869 : Improvements to MetadataParser for annotation support
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/6d94f0e3
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/6d94f0e3
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/6d94f0e3
Branch: refs/heads/OLINGO-832_StreamSerializerPoC
Commit: 6d94f0e386b7f3126f1023c87c78670fb55e2d5a
Parents: b317b90
Author: Ramesh Reddy <ra...@jboss.org>
Authored: Sat Feb 6 13:31:26 2016 -0600
Committer: Ramesh Reddy <ra...@jboss.org>
Committed: Sat Feb 6 13:31:26 2016 -0600
----------------------------------------------------------------------
.../commons/api/edm/provider/CsdlOnDelete.java | 23 +-
.../api/edm/provider/CsdlReturnType.java | 23 +-
.../olingo/server/api/edmx/EdmxReference.java | 24 +-
.../olingo/server/core/MetadataParser.java | 498 ++++++++++--
.../core/MetadataParserAnnotationsTest.java | 208 +++++
.../olingo/server/core/MetadataParserTest.java | 3 +-
.../server/core/ServiceDispatcherTest.java | 17 +-
.../olingo/server/example/TripPinServlet.java | 9 +-
.../src/test/resources/annotations.xml | 153 ++++
.../src/test/resources/trippin.xml | 808 +++++++++++--------
10 files changed, 1311 insertions(+), 455 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6d94f0e3/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/provider/CsdlOnDelete.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/provider/CsdlOnDelete.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/provider/CsdlOnDelete.java
index 1a326dd..e3ed711 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/provider/CsdlOnDelete.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/provider/CsdlOnDelete.java
@@ -18,13 +18,17 @@
*/
package org.apache.olingo.commons.api.edm.provider;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* The type Csdl on delete.
*/
-public class CsdlOnDelete extends CsdlAbstractEdmItem {
+public class CsdlOnDelete extends CsdlAbstractEdmItem implements CsdlAnnotatable {
private CsdlOnDeleteAction action = CsdlOnDeleteAction.None;
-
+
+ private List<CsdlAnnotation> annotations = new ArrayList<CsdlAnnotation>();
/**
* Gets action.
*
@@ -45,4 +49,19 @@ public class CsdlOnDelete extends CsdlAbstractEdmItem {
return this;
}
+ @Override
+ public List<CsdlAnnotation> getAnnotations() {
+ return annotations;
+ }
+
+ /**
+ * Sets annotations.
+ *
+ * @param annotations the annotations
+ * @return the annotations
+ */
+ public CsdlOnDelete setAnnotations(final List<CsdlAnnotation> annotations) {
+ this.annotations = annotations;
+ return this;
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6d94f0e3/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/provider/CsdlReturnType.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/provider/CsdlReturnType.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/provider/CsdlReturnType.java
index eb94acc..e5cee4e 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/provider/CsdlReturnType.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/provider/CsdlReturnType.java
@@ -18,13 +18,16 @@
*/
package org.apache.olingo.commons.api.edm.provider;
+import java.util.ArrayList;
+import java.util.List;
+
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.geo.SRID;
/**
* The type Csdl return type.
*/
-public class CsdlReturnType extends CsdlAbstractEdmItem {
+public class CsdlReturnType extends CsdlAbstractEdmItem implements CsdlAnnotatable {
private String type;
@@ -40,6 +43,8 @@ public class CsdlReturnType extends CsdlAbstractEdmItem {
private Integer scale;
private SRID srid;
+
+ private List<CsdlAnnotation> annotations = new ArrayList<CsdlAnnotation>();
/**
* Gets type.
@@ -200,4 +205,20 @@ public class CsdlReturnType extends CsdlAbstractEdmItem {
this.srid = srid;
return this;
}
+
+ @Override
+ public List<CsdlAnnotation> getAnnotations() {
+ return annotations;
+ }
+
+ /**
+ * Sets annotations.
+ *
+ * @param annotations the annotations
+ * @return the annotations
+ */
+ public CsdlReturnType setAnnotations(final List<CsdlAnnotation> annotations) {
+ this.annotations = annotations;
+ return this;
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6d94f0e3/lib/commons-api/src/main/java/org/apache/olingo/server/api/edmx/EdmxReference.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/server/api/edmx/EdmxReference.java b/lib/commons-api/src/main/java/org/apache/olingo/server/api/edmx/EdmxReference.java
index 38d17fe..e1b735b 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/server/api/edmx/EdmxReference.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/server/api/edmx/EdmxReference.java
@@ -23,15 +23,19 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import org.apache.olingo.commons.api.edm.provider.CsdlAnnotatable;
+import org.apache.olingo.commons.api.edm.provider.CsdlAnnotation;
+import org.apache.olingo.commons.api.edm.provider.CsdlReturnType;
+
/**
* POJO for Edmx Reference.
*/
-public class EdmxReference {
+public class EdmxReference implements CsdlAnnotatable{
private final URI uri;
private final List<EdmxReferenceInclude> edmxIncludes;
private final List<EdmxReferenceIncludeAnnotation> edmxIncludeAnnotations;
-
+ private List<CsdlAnnotation> annotations = new ArrayList<CsdlAnnotation>();
/**
* Create reference with given uri
*
@@ -90,4 +94,20 @@ public class EdmxReference {
edmxIncludeAnnotations.add(includeAnnotation);
return this;
}
+
+ @Override
+ public List<CsdlAnnotation> getAnnotations() {
+ return annotations;
+ }
+
+ /**
+ * Sets annotations.
+ *
+ * @param annotations the annotations
+ * @return the annotations
+ */
+ public EdmxReference setAnnotations(final List<CsdlAnnotation> annotations) {
+ this.annotations = annotations;
+ return this;
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6d94f0e3/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
index b5ffd4a..e8122d7 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
@@ -19,9 +19,10 @@
package org.apache.olingo.server.core;
import java.io.Reader;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+import java.util.Arrays;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
@@ -36,6 +37,10 @@ import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.geo.SRID;
import org.apache.olingo.commons.api.edm.provider.CsdlAction;
import org.apache.olingo.commons.api.edm.provider.CsdlActionImport;
+import org.apache.olingo.commons.api.edm.provider.CsdlAnnotatable;
+import org.apache.olingo.commons.api.edm.provider.CsdlAnnotation;
+import org.apache.olingo.commons.api.edm.provider.CsdlAnnotations;
+import org.apache.olingo.commons.api.edm.provider.CsdlBindingTarget;
import org.apache.olingo.commons.api.edm.provider.CsdlComplexType;
import org.apache.olingo.commons.api.edm.provider.CsdlEdmProvider;
import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer;
@@ -59,33 +64,91 @@ import org.apache.olingo.commons.api.edm.provider.CsdlSchema;
import org.apache.olingo.commons.api.edm.provider.CsdlSingleton;
import org.apache.olingo.commons.api.edm.provider.CsdlTerm;
import org.apache.olingo.commons.api.edm.provider.CsdlTypeDefinition;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlAnnotationPath;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlApply;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlCast;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlCollection;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlConstantExpression;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlConstantExpression.ConstantExpressionType;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlExpression;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlIf;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlIsOf;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlLabeledElement;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlLabeledElementReference;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlNavigationPropertyPath;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlNull;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlPath;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlPropertyPath;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlPropertyValue;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlRecord;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlUrlRef;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.edmx.EdmxReference;
+import org.apache.olingo.server.api.edmx.EdmxReferenceInclude;
+import org.apache.olingo.server.api.edmx.EdmxReferenceIncludeAnnotation;
/**
* This class can convert a CSDL document into EDMProvider object
*/
public class MetadataParser {
+ private boolean parseAnnotations = false;
- public CsdlEdmProvider buildEdmProvider(Reader csdl) throws XMLStreamException {
+ public void setParseAnnotations(boolean f) {
+ this.parseAnnotations = true;
+ }
+
+ public ServiceMetadata buildServiceMetadata(Reader csdl) throws XMLStreamException {
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
XMLEventReader reader = xmlInputFactory.createXMLEventReader(csdl);
SchemaBasedEdmProvider provider = new SchemaBasedEdmProvider();
+ final ArrayList<EdmxReference> references = new ArrayList<EdmxReference>();
+
new ElementReader<SchemaBasedEdmProvider>() {
@Override
void build(XMLEventReader reader, StartElement element, SchemaBasedEdmProvider provider,
String name) throws XMLStreamException {
String version = attr(element, "Version");
if ("4.0".equals(version)) {
- readDataServicesAndReference(reader, element, provider);
+ readDataServicesAndReference(reader, element, provider, references);
+ } else {
+ throw new XMLStreamException("Currently only V4 is supported.");
}
}
}.read(reader, null, provider, "Edmx");
-
- return provider;
+ if(reader.hasNext()) {
+ XMLEvent event = reader.peek();
+ throw new XMLStreamException(
+ "Failed to read complete metadata file. Failed at "
+ + (event.isStartElement() ?
+ event.asStartElement().getName().getLocalPart() :
+ event.asEndElement().getName().getLocalPart()));
+ }
+ return new ServiceMetadataImpl(provider, references, null);
}
- private void readDataServicesAndReference(XMLEventReader reader, StartElement element,
- SchemaBasedEdmProvider provider) throws XMLStreamException {
+ CsdlEdmProvider buildEdmProvider(Reader csdl) throws XMLStreamException {
+ XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
+ XMLEventReader reader = xmlInputFactory.createXMLEventReader(csdl);
+
+ SchemaBasedEdmProvider provider = new SchemaBasedEdmProvider();
+ new ElementReader<SchemaBasedEdmProvider>() {
+ @Override
+ void build(XMLEventReader reader, StartElement element, SchemaBasedEdmProvider provider,
+ String name) throws XMLStreamException {
+ String version = attr(element, "Version");
+ if ("4.0".equals(version)) {
+ readDataServicesAndReference(reader, element, provider, new ArrayList<EdmxReference>());
+ }
+ }
+ }.read(reader, null, provider, "Edmx");
+
+ return provider;
+ }
+
+ private void readDataServicesAndReference(XMLEventReader reader,
+ StartElement element, SchemaBasedEdmProvider provider,
+ final ArrayList<EdmxReference> references) throws XMLStreamException {
new ElementReader<SchemaBasedEdmProvider>() {
@Override
void build(XMLEventReader reader, StartElement element, SchemaBasedEdmProvider provider,
@@ -93,45 +156,64 @@ public class MetadataParser {
if (name.equals("DataServices")) {
readSchema(reader, element, provider);
} else if (name.equals("Reference")) {
- readReference(reader, element, provider, "Reference");
+ readReference(reader, element, references, "Reference");
}
}
}.read(reader, element, provider, "DataServices", "Reference");
}
private void readReference(XMLEventReader reader, StartElement element,
- SchemaBasedEdmProvider provider, String name) throws XMLStreamException {
- new ElementReader<SchemaBasedEdmProvider>() {
+ final ArrayList<EdmxReference> references, String name) throws XMLStreamException {
+ EdmxReference reference;
+ try {
+ String uri = attr(element, "Uri");
+ reference = new EdmxReference(new URI(uri));
+ } catch (URISyntaxException e) {
+ throw new XMLStreamException(e);
+ }
+ new ElementReader<EdmxReference>() {
@Override
- void build(XMLEventReader reader, StartElement element, SchemaBasedEdmProvider t, String name)
- throws XMLStreamException {
- // TODO:
+ void build(XMLEventReader reader, StartElement element,
+ EdmxReference reference, String name) throws XMLStreamException {
+ if (name.equals("Include")) {
+ EdmxReferenceInclude include = new EdmxReferenceInclude(attr(element, "Namespace"),
+ attr(element, "Alias"));
+ reference.addInclude(include);
+ } else if (name.equals("IncludeAnnotations")) {
+ EdmxReferenceIncludeAnnotation annotation = new EdmxReferenceIncludeAnnotation(
+ attr(element, "TermNamespace"));
+ annotation.setTargetNamespace(attr(element, "TargetNamespace"));
+ annotation.setQualifier(attr(element, "Qualifier"));
+ reference.addIncludeAnnotation(annotation);
+ } else if (name.equals("Annotation")) {
+ readAnnotations(reader, element, reference);
+ }
}
- }.read(reader, element, provider, name);
+ }.read(reader, element, reference, "Include", "IncludeAnnotations", "Annotation");
+ references.add(reference);
}
-
+
private void readSchema(XMLEventReader reader, StartElement element,
SchemaBasedEdmProvider provider) throws XMLStreamException {
- CsdlSchema schema = new CsdlSchema();
- schema.setComplexTypes(new ArrayList<CsdlComplexType>());
- schema.setActions(new ArrayList<CsdlAction>());
- schema.setEntityTypes(new ArrayList<CsdlEntityType>());
- schema.setEnumTypes(new ArrayList<CsdlEnumType>());
- schema.setFunctions(new ArrayList<CsdlFunction>());
- schema.setTerms(new ArrayList<CsdlTerm>());
- schema.setTypeDefinitions(new ArrayList<CsdlTypeDefinition>());
-
- new ElementReader<CsdlSchema>() {
+ new ElementReader<SchemaBasedEdmProvider>() {
@Override
- void build(XMLEventReader reader, StartElement element, CsdlSchema schema, String name)
+ void build(XMLEventReader reader, StartElement element, SchemaBasedEdmProvider provider, String name)
throws XMLStreamException {
+ CsdlSchema schema = new CsdlSchema();
+ schema.setComplexTypes(new ArrayList<CsdlComplexType>());
+ schema.setActions(new ArrayList<CsdlAction>());
+ schema.setEntityTypes(new ArrayList<CsdlEntityType>());
+ schema.setEnumTypes(new ArrayList<CsdlEnumType>());
+ schema.setFunctions(new ArrayList<CsdlFunction>());
+ schema.setTerms(new ArrayList<CsdlTerm>());
+ schema.setTypeDefinitions(new ArrayList<CsdlTypeDefinition>());
schema.setNamespace(attr(element, "Namespace"));
schema.setAlias(attr(element, "Alias"));
readSchemaContents(reader, schema);
+ provider.addSchema(schema);
}
- }.read(reader, element, schema, "Schema");
- provider.addSchema(schema);
+ }.read(reader, element, provider, "Schema");
}
private void readSchemaContents(XMLEventReader reader, CsdlSchema schema) throws XMLStreamException {
@@ -141,9 +223,10 @@ public class MetadataParser {
throws XMLStreamException {
if (name.equals("Action")) {
readAction(reader, element, schema);
-// } else if (name.equals("Annotations")) {
-// } else if (name.equals("Annotation")) {
- // TODO: Add support for annotations
+ } else if (name.equals("Annotations")) {
+ readAnnotationGroup(reader, element, schema);
+ } else if (name.equals("Annotation")) {
+ readAnnotations(reader, element, schema);
} else if (name.equals("ComplexType")) {
readComplexType(reader, element, schema);
} else if (name.equals("EntityContainer")) {
@@ -155,9 +238,9 @@ public class MetadataParser {
} else if (name.equals("Function")) {
readFunction(reader, element, schema);
} else if (name.equals("Term")) {
- schema.getTerms().add(readTerm(element));
+ schema.getTerms().add(readTerm(reader, element));
} else if (name.equals("TypeDefinition")) {
- schema.getTypeDefinitions().add(readTypeDefinition(element));
+ schema.getTypeDefinitions().add(readTypeDefinition(reader, element));
}
}
}.read(reader, null, schema, "Action", "Annotations", "Annotation", "ComplexType",
@@ -196,7 +279,8 @@ public class MetadataParser {
return false;
}
- private void readReturnType(StartElement element, CsdlOperation operation) {
+ private void readReturnType(XMLEventReader reader, StartElement element,
+ CsdlOperation operation) throws XMLStreamException {
CsdlReturnType returnType = new CsdlReturnType();
returnType.setType(readType(element));
returnType.setCollection(isCollectionType(element));
@@ -216,13 +300,14 @@ public class MetadataParser {
}
String srid = attr(element, "SRID");
if (srid != null) {
- // TODO: no olingo support yet.
returnType.setSrid(SRID.valueOf(srid));
}
+ peekAnnotations(reader, element.getName().getLocalPart(), returnType);
operation.setReturnType(returnType);
}
- private void readParameter(StartElement element, CsdlOperation operation) {
+ private void readParameter(XMLEventReader reader, StartElement element,
+ CsdlOperation operation) throws XMLStreamException {
CsdlParameter parameter = new CsdlParameter();
parameter.setName(attr(element, "Name"));
parameter.setType(readType(element));
@@ -243,13 +328,14 @@ public class MetadataParser {
}
String srid = attr(element, "SRID");
if (srid != null) {
- // TODO: no olingo support yet.
parameter.setSrid(SRID.valueOf(srid));
}
+ peekAnnotations(reader, element.getName().getLocalPart(), parameter);
operation.getParameters().add(parameter);
}
- private CsdlTypeDefinition readTypeDefinition(StartElement element) {
+ private CsdlTypeDefinition readTypeDefinition(XMLEventReader reader,
+ StartElement element) throws XMLStreamException {
CsdlTypeDefinition td = new CsdlTypeDefinition();
td.setName(attr(element, "Name"));
td.setUnderlyingType(new FullQualifiedName(attr(element, "UnderlyingType")));
@@ -269,16 +355,17 @@ public class MetadataParser {
}
String srid = attr(element, "SRID");
if (srid != null) {
- // TODO: no olingo support yet.
td.setSrid(SRID.valueOf(srid));
}
+ peekAnnotations(reader, element.getName().getLocalPart(), td);
return td;
}
- private CsdlTerm readTerm(StartElement element) {
+ private CsdlTerm readTerm(XMLEventReader reader, StartElement element) throws XMLStreamException {
CsdlTerm term = new CsdlTerm();
term.setName(attr(element, "Name"));
term.setType(attr(element, "Type"));
+
if (attr(element, "BaseTerm") != null) {
term.setBaseTerm(attr(element, "BaseTerm"));
}
@@ -286,7 +373,8 @@ public class MetadataParser {
term.setDefaultValue(attr(element, "DefaultValue"));
}
if (attr(element, "AppliesTo") != null) {
- term.setAppliesTo(Collections.singletonList(attr(element, "AppliesTo")));
+ String[] appliesTo = attr(element, "AppliesTo").split("\\s+");
+ term.setAppliesTo(Arrays.asList(appliesTo));
}
term.setNullable(Boolean.parseBoolean(attr(element, "Nullable")));
String maxLength = attr(element, "MaxLength");
@@ -303,12 +391,231 @@ public class MetadataParser {
}
String srid = attr(element, "SRID");
if (srid != null) {
- // TODO: no olingo support yet.
term.setSrid(SRID.valueOf(srid));
}
+ peekAnnotations(reader, "Term", term);
return term;
}
+ private void readAnnotationGroup(XMLEventReader reader, StartElement element,
+ CsdlSchema schema) throws XMLStreamException {
+ final CsdlAnnotations annotations = new CsdlAnnotations();
+ annotations.setTarget(attr(element, "Target"));
+ annotations.setQualifier(attr(element, "Qualifier"));
+ readAnnotations(reader, element, annotations);
+ schema.getAnnotationGroups().add(annotations);
+ }
+
+ private void peekAnnotations(XMLEventReader reader, String endName,
+ CsdlAnnotatable edmObject) throws XMLStreamException {
+ if(!parseAnnotations) {
+ return;
+ }
+ while (reader.hasNext()) {
+ XMLEvent event = reader.peek();
+
+ if (!event.isStartElement() && !event.isEndElement()) {
+ reader.nextEvent();
+ continue;
+ }
+
+ if (event.isStartElement()) {
+ StartElement element = event.asStartElement();
+ if (element.getName().getLocalPart().equals("Annotation")) {
+ reader.nextEvent();
+ readAnnotations(reader, element, edmObject);
+ }
+ }
+
+ if (event.isEndElement()) {
+ EndElement element = event.asEndElement();
+ if (element.getName().getLocalPart().equals("Annotation")) {
+ reader.nextEvent();
+ }
+
+ if (element.getName().getLocalPart().equals(endName)) {
+ return;
+ }
+ }
+ }
+ }
+
+ private void readAnnotations(XMLEventReader reader, StartElement element,
+ CsdlAnnotatable edmObject) throws XMLStreamException {
+ if (!parseAnnotations) {
+ return;
+ }
+ final CsdlAnnotation annotation = new CsdlAnnotation();
+ annotation.setTerm(attr(element, "Term"));
+ for (ConstantExpressionType type:ConstantExpressionType.values()) {
+ if (attr(element, type.name()) != null) {
+ annotation.setExpression(new CsdlConstantExpression(
+ type, attr(element, type.name())));
+ }
+ }
+ readExpressions(reader, element, annotation);
+ edmObject.getAnnotations().add(annotation);
+ }
+
+ private <T> void write(T t, CsdlExpression expr) throws XMLStreamException {
+ if(t instanceof CsdlAnnotation) {
+ ((CsdlAnnotation)t).setExpression(expr);
+ } else if (t instanceof CsdlUrlRef) {
+ ((CsdlUrlRef)t).setValue(expr);
+ } else if (t instanceof CsdlCast) {
+ ((CsdlCast)t).setValue(expr);
+ } else if (t instanceof CsdlLabeledElement) {
+ ((CsdlLabeledElement)t).setValue(expr);
+ } else if (t instanceof CsdlIsOf) {
+ ((CsdlIsOf)t).setValue(expr);
+ } else if (t instanceof CsdlCollection) {
+ ((CsdlCollection)t).getItems().add(((CsdlCollection)t).getItems().size(), expr);
+ } else if (t instanceof CsdlApply) {
+ ((CsdlApply)t).getParameters().add(expr);
+ } else if (t instanceof CsdlIf) {
+ if (((CsdlIf)t).getGuard() == null) {
+ ((CsdlIf)t).setGuard(expr);
+ } else if (((CsdlIf)t).getThen() == null) {
+ ((CsdlIf)t).setThen(expr);
+ } else {
+ ((CsdlIf)t).setElse(expr);
+ }
+ } else if (t instanceof CsdlPropertyValue) {
+ ((CsdlPropertyValue)t).setValue(expr);
+ } else {
+ throw new XMLStreamException("Unknown expression parent in Annoatation");
+ }
+ }
+
+ private <T> void readExpressions(XMLEventReader reader,
+ StartElement element, T target)
+ throws XMLStreamException {
+ new ElementReader<T>() {
+ @Override
+ void build(XMLEventReader reader, StartElement element, T target, String name)
+ throws XMLStreamException {
+
+ // attribute based expressions
+ if (attr(element, "AnnotationPath") != null) {
+ write(target, new CsdlAnnotationPath().setValue(attr(element, "AnnotationPath")));
+ }
+ if (attr(element, "NavigationPropertyPath") != null) {
+ write(target, new CsdlNavigationPropertyPath()
+ .setValue(attr(element, "NavigationPropertyPath")));
+ }
+ if (attr(element, "Path") != null) {
+ write(target, new CsdlPath().setValue(attr(element, "Path")));
+ }
+ if (attr(element, "PropertyPath") != null) {
+ write(target, new CsdlPropertyPath().setValue(attr(element, "PropertyPath")));
+ }
+ if (attr(element, "UrlRef") != null) {
+ write(target, new CsdlUrlRef().setValue(new CsdlConstantExpression(
+ ConstantExpressionType.String, attr(element, "UrlRef"))));
+ }
+
+ // element based expressions
+ for (ConstantExpressionType type:ConstantExpressionType.values()) {
+ if (name.equals(type.name())) {
+ if (reader.peek().isCharacters()) {
+ CsdlExpression expr = new CsdlConstantExpression(type, elementValue(reader, element));
+ write(target, expr);
+ }
+ }
+ }
+ if (name.equals("Collection")) {
+ CsdlCollection expr = new CsdlCollection();
+ readExpressions(reader, element, expr);
+ write(target, expr);
+ } else if (name.equals("AnnotationPath")) {
+ write(target, new CsdlAnnotationPath().setValue(elementValue(reader, element)));
+ } else if (name.equals("NavigationPropertyPath")) {
+ write(target, new CsdlNavigationPropertyPath()
+ .setValue(elementValue(reader, element)));
+ } else if (name.equals("Path")) {
+ write(target, new CsdlPath().setValue(elementValue(reader, element)));
+ } else if (name.equals("PropertyPath")) {
+ write(target, new CsdlPropertyPath().setValue(elementValue(reader, element)));
+ } else if (name.equals("UrlRef")) {
+ CsdlUrlRef expr = new CsdlUrlRef();
+ readExpressions(reader, element, expr);
+ write(target, expr);
+ } else if (name.equals("Apply")) {
+ CsdlApply expr = new CsdlApply();
+ expr.setFunction(attr(element, "Function"));
+ readExpressions(reader, element, expr);
+ write(target, expr);
+ } else if (name.equals("Cast")) {
+ CsdlCast expr = new CsdlCast();
+ expr.setType(attr(element, "Type"));
+ readExpressions(reader, element, expr);
+ write(target, expr);
+ } else if (name.equals("If")) {
+ CsdlIf expr = new CsdlIf();
+ readExpressions(reader, element, expr);
+ write(target, expr);
+ } else if (name.equals("IsOf")) {
+ CsdlIsOf expr = new CsdlIsOf();
+ expr.setType(attr(element, "Type"));
+ readExpressions(reader, element, expr);
+ write(target, expr);
+ } else if (name.equals("LabeledElement")) {
+ CsdlLabeledElement expr = new CsdlLabeledElement();
+ expr.setName(attr(element, "Name"));
+ readExpressions(reader, element, expr);
+ write(target, expr);
+ } else if (name.equals("LabeledElementReference")) {
+ CsdlLabeledElementReference expr = new CsdlLabeledElementReference();
+ expr.setValue(elementValue(reader, element));
+ write(target, expr);
+ } else if (name.equals("Null")) {
+ write(target, new CsdlNull());
+ } else if (name.equals("Record")) {
+ CsdlRecord expr = new CsdlRecord();
+ expr.setType(attr(element, "Type"));
+ readPropertyValues(reader, element, expr);
+ write(target, expr);
+ }
+ }
+ }.read(reader, element, target, "Collection", "AnnotationPath",
+ "NavigationPropertyPath", "Path", "PropertyPath", "UrlRef",
+ "Apply", "Function", "Cast", "If", "IsOf", "LabeledElement",
+ "LabeledElementReference", "Null", "Record","Binary", "Bool", "Date",
+ "DateTimeOffset", "Decimal", "Duration", "EnumMember", "Float", "Guid",
+ "Int", "String", "TimeOfDay");
+ }
+
+ private String elementValue(XMLEventReader reader, StartElement element) throws XMLStreamException {
+ while (reader.hasNext()) {
+ XMLEvent event = reader.peek();
+ if (event.isStartElement() || event.isEndElement()) {
+ return null;
+ } else if (event.isCharacters()){
+ reader.nextEvent();
+ String data = event.asCharacters().getData();
+ if (data.trim().length() > 0) {
+ return data.trim();
+ }
+ }
+ }
+ return null;
+ }
+
+ private void readPropertyValues(XMLEventReader reader,
+ StartElement element, CsdlRecord record) throws XMLStreamException {
+
+ new ElementReader<CsdlRecord>() {
+ @Override
+ void build(XMLEventReader reader, StartElement element, CsdlRecord record, String name)
+ throws XMLStreamException {
+ CsdlPropertyValue value = new CsdlPropertyValue();
+ value.setProperty(attr(element, "Property"));
+ readExpressions(reader, element, value);
+ record.getPropertyValues().add(value);
+ }
+ }.read(reader, element, record, "PropertyValue");
+ }
+
private void readFunction(XMLEventReader reader, StartElement element, CsdlSchema schema)
throws XMLStreamException {
CsdlFunction function = new CsdlFunction();
@@ -332,12 +639,14 @@ public class MetadataParser {
void build(XMLEventReader reader, StartElement element, CsdlOperation operation, String name)
throws XMLStreamException {
if (name.equals("Parameter")) {
- readParameter(element, operation);
+ readParameter(reader, element, operation);
} else if (name.equals("ReturnType")) {
- readReturnType(element, operation);
+ readReturnType(reader, element, operation);
+ } else if (name.equals("Annotation")) {
+ readAnnotations(reader, element, operation);
}
}
- }.read(reader, null, operation, "Parameter", "ReturnType");
+ }.read(reader, null, operation, "Parameter", "ReturnType", "Annotation");
}
private void readEnumType(XMLEventReader reader, StartElement element, CsdlSchema schema)
@@ -356,16 +665,22 @@ public class MetadataParser {
private void readEnumMembers(XMLEventReader reader, StartElement element, CsdlEnumType type)
throws XMLStreamException {
+
new ElementReader<CsdlEnumType>() {
@Override
void build(XMLEventReader reader, StartElement element, CsdlEnumType type, String name)
throws XMLStreamException {
- CsdlEnumMember member = new CsdlEnumMember();
- member.setName(attr(element, "Name"));
- member.setValue(attr(element, "Value"));
- type.getMembers().add(member);
+ if (name.equals("Member")) {
+ CsdlEnumMember member = new CsdlEnumMember();
+ member.setName(attr(element, "Name"));
+ member.setValue(attr(element, "Value"));
+ peekAnnotations(reader, name, member);
+ type.getMembers().add(member);
+ } else if (name.equals("Annotation")) {
+ readAnnotations(reader, element, type);
+ }
}
- }.read(reader, element, type, "Member");
+ }.read(reader, element, type, "Member", "Annotation");
}
private void readEntityType(XMLEventReader reader, StartElement element, CsdlSchema schema)
@@ -392,14 +707,16 @@ public class MetadataParser {
void build(XMLEventReader reader, StartElement element, CsdlEntityType entityType, String name)
throws XMLStreamException {
if (name.equals("Property")) {
- entityType.getProperties().add(readProperty(element));
+ entityType.getProperties().add(readProperty(reader, element));
} else if (name.equals("NavigationProperty")) {
entityType.getNavigationProperties().add(readNavigationProperty(reader, element));
} else if (name.equals("Key")) {
readKey(reader, element, entityType);
+ } else if (name.equals("Annotation")) {
+ readAnnotations(reader, element, entityType);
}
}
- }.read(reader, null, entityType, "Property", "NavigationProperty", "Key");
+ }.read(reader, null, entityType, "Property", "NavigationProperty", "Key", "Annotation");
}
private void readKey(XMLEventReader reader, StartElement element, CsdlEntityType entityType)
@@ -436,12 +753,18 @@ public class MetadataParser {
CsdlReferentialConstraint constraint = new CsdlReferentialConstraint();
constraint.setProperty(attr(element, "Property"));
constraint.setReferencedProperty(attr(element, "ReferencedProperty"));
+ peekAnnotations(reader, name, constraint);
property.getReferentialConstraints().add(constraint);
} else if (name.equals("OnDelete")) {
- property.setOnDelete(new CsdlOnDelete().setAction(CsdlOnDeleteAction.valueOf(attr(element, "Action"))));
+ CsdlOnDelete delete = new CsdlOnDelete();
+ delete.setAction(CsdlOnDeleteAction.valueOf(attr(element, "Action")));
+ property.setOnDelete(delete);
+ peekAnnotations(reader, name, delete);
+ } else if (name.equals("Annotation")) {
+ readAnnotations(reader, element, property);
}
}
- }.read(reader, element, property, "ReferentialConstraint", "OnDelete");
+ }.read(reader, element, property, "ReferentialConstraint", "OnDelete", "Annotation");
return property;
}
@@ -453,7 +776,8 @@ public class MetadataParser {
return null;
}
- private CsdlProperty readProperty(StartElement element) {
+ private CsdlProperty readProperty(XMLEventReader reader, StartElement element)
+ throws XMLStreamException {
CsdlProperty property = new CsdlProperty();
property.setName(attr(element, "Name"));
property.setType(readType(element));
@@ -476,13 +800,13 @@ public class MetadataParser {
}
String srid = attr(element, "SRID");
if (srid != null) {
- // TODO: no olingo support yet.
property.setSrid(SRID.valueOf(srid));
}
String defaultValue = attr(element, "DefaultValue");
if (defaultValue != null) {
property.setDefaultValue(defaultValue);
}
+ peekAnnotations(reader, element.getName().getLocalPart(), property);
return property;
}
@@ -507,13 +831,17 @@ public class MetadataParser {
} else if (name.equals("Singleton")) {
readSingleton(reader, element, container);
} else if (name.equals("ActionImport")) {
- readActionImport(element, container);
+ readActionImport(reader, element, container);
} else if (name.equals("FunctionImport")) {
- readFunctionImport(element, container);
+ readFunctionImport(reader, element, container);
+ } else if (name.equals("Annotation")) {
+ readAnnotations(reader, element, container);
}
}
- private void readFunctionImport(StartElement element, CsdlEntityContainer container) {
+ private void readFunctionImport(XMLEventReader reader,
+ StartElement element, CsdlEntityContainer container)
+ throws XMLStreamException {
CsdlFunctionImport functionImport = new CsdlFunctionImport();
functionImport.setName(attr(element, "Name"));
functionImport.setFunction(new FullQualifiedName(attr(element, "Function")));
@@ -524,10 +852,13 @@ public class MetadataParser {
if (entitySet != null) {
functionImport.setEntitySet(entitySet);
}
+ peekAnnotations(reader, "FunctionImport", functionImport);
container.getFunctionImports().add(functionImport);
}
- private void readActionImport(StartElement element, CsdlEntityContainer container) {
+ private void readActionImport(XMLEventReader reader,
+ StartElement element, CsdlEntityContainer container)
+ throws XMLStreamException {
CsdlActionImport actionImport = new CsdlActionImport();
actionImport.setName(attr(element, "Name"));
actionImport.setAction(new FullQualifiedName(attr(element, "Action")));
@@ -536,6 +867,7 @@ public class MetadataParser {
if (entitySet != null) {
actionImport.setEntitySet(entitySet);
}
+ peekAnnotations(reader, "ActionImport", actionImport);
container.getActionImports().add(actionImport);
}
@@ -546,7 +878,7 @@ public class MetadataParser {
singleton.setName(attr(element, "Name"));
singleton.setType(new FullQualifiedName(attr(element, "Type")));
singleton.setNavigationPropertyBindings(new ArrayList<CsdlNavigationPropertyBinding>());
- readNavigationPropertyBindings(reader, element, singleton.getNavigationPropertyBindings());
+ readNavigationPropertyBindings(reader, element, singleton);
container.getSingletons().add(singleton);
}
@@ -558,25 +890,29 @@ public class MetadataParser {
entitySet.setIncludeInServiceDocument(Boolean.parseBoolean(attr(element,
"IncludeInServiceDocument")));
entitySet.setNavigationPropertyBindings(new ArrayList<CsdlNavigationPropertyBinding>());
- readNavigationPropertyBindings(reader, element, entitySet.getNavigationPropertyBindings());
+ readNavigationPropertyBindings(reader, element, entitySet);
container.getEntitySets().add(entitySet);
}
private void readNavigationPropertyBindings(XMLEventReader reader, StartElement element,
- List<CsdlNavigationPropertyBinding> bindings) throws XMLStreamException {
- new ElementReader<List<CsdlNavigationPropertyBinding>>() {
+ CsdlBindingTarget entitySet) throws XMLStreamException {
+ new ElementReader<CsdlBindingTarget>() {
@Override
void build(XMLEventReader reader, StartElement element,
- List<CsdlNavigationPropertyBinding> bindings, String name) throws XMLStreamException {
- CsdlNavigationPropertyBinding binding = new CsdlNavigationPropertyBinding();
- binding.setPath(attr(element, "Path"));
- binding.setTarget(attr(element, "Target"));
- bindings.add(binding);
+ CsdlBindingTarget entitySet, String name) throws XMLStreamException {
+ if (name.equals("NavigationPropertyBinding")) {
+ CsdlNavigationPropertyBinding binding = new CsdlNavigationPropertyBinding();
+ binding.setPath(attr(element, "Path"));
+ binding.setTarget(attr(element, "Target"));
+ entitySet.getNavigationPropertyBindings().add(binding);
+ } else if (name.equals("Annotation")) {
+ readAnnotations(reader, element, entitySet);
+ }
}
- }.read(reader, element, bindings, "NavigationPropertyBinding");
+ }.read(reader, element, entitySet, "NavigationPropertyBinding", "Annotation");
}
- }.read(reader, element, schema, "EntitySet", "Singleton", "ActionImport", "FunctionImport");
+ }.read(reader, element, schema, "EntitySet", "Singleton", "ActionImport", "FunctionImport", "Annotation");
schema.setEntityContainer(container);
}
@@ -603,12 +939,14 @@ public class MetadataParser {
void build(XMLEventReader reader, StartElement element, CsdlComplexType complexType, String name)
throws XMLStreamException {
if (name.equals("Property")) {
- complexType.getProperties().add(readProperty(element));
+ complexType.getProperties().add(readProperty(reader, element));
} else if (name.equals("NavigationProperty")) {
complexType.getNavigationProperties().add(readNavigationProperty(reader, element));
+ } else if (name.equals("Annotation")) {
+ readAnnotations(reader, element, complexType);
}
}
- }.read(reader, null, complexType, "Property", "NavigationProperty");
+ }.read(reader, null, complexType, "Property", "NavigationProperty", "Annotation");
}
abstract class ElementReader<T> {
@@ -617,7 +955,9 @@ public class MetadataParser {
while (reader.hasNext()) {
XMLEvent event = reader.peek();
- event = skipAnnotations(reader, event);
+ if (!parseAnnotations) {
+ event = skipAnnotations(reader, event);
+ }
if (!event.isStartElement() && !event.isEndElement()) {
reader.nextEvent();
@@ -629,17 +969,19 @@ public class MetadataParser {
for (String name : names) {
if (event.isStartElement()) {
element = event.asStartElement();
- if (element.getName().getLocalPart().equals(name)) {
- reader.nextEvent(); // advance cursor
+ if (element.getName().getLocalPart().equals(name)) {
+ reader.nextEvent(); // advance cursor start which is current
build(reader, element, t, name);
hit = true;
+ break;
}
}
if (event.isEndElement()) {
EndElement e = event.asEndElement();
if (e.getName().getLocalPart().equals(name)) {
- reader.nextEvent(); // advance cursor
+ reader.nextEvent(); // advance cursor to end which is current
hit = true;
+ break;
}
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6d94f0e3/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserAnnotationsTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserAnnotationsTest.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserAnnotationsTest.java
new file mode 100644
index 0000000..7912dc8
--- /dev/null
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserAnnotationsTest.java
@@ -0,0 +1,208 @@
+/*
+ * 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.server.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.FileReader;
+import java.util.Arrays;
+
+import org.apache.olingo.commons.api.edm.FullQualifiedName;
+import org.apache.olingo.commons.api.edm.provider.CsdlAnnotation;
+import org.apache.olingo.commons.api.edm.provider.CsdlEdmProvider;
+import org.apache.olingo.commons.api.edm.provider.CsdlSchema;
+import org.apache.olingo.commons.api.edm.provider.CsdlTerm;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlAnnotationPath;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlApply;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlCast;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlCollection;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlConstantExpression;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlConstantExpression.ConstantExpressionType;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlIf;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlIsOf;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlLabeledElement;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlLabeledElementReference;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlNavigationPropertyPath;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlNull;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlPath;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlPropertyValue;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlRecord;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlUrlRef;
+import org.apache.olingo.commons.api.ex.ODataException;
+import org.junit.Before;
+import org.junit.Test;
+
+public class MetadataParserAnnotationsTest {
+ final String NS = "Org.OData.Core.V1";
+ final FullQualifiedName NSF = new FullQualifiedName(NS);
+
+ CsdlEdmProvider provider = null;
+
+ @Before
+ public void setUp() throws Exception {
+ MetadataParser parser = new MetadataParser();
+ parser.setParseAnnotations(true);
+ provider = (CsdlEdmProvider) parser.buildEdmProvider(new FileReader("src/test/resources/annotations.xml"));
+ }
+
+ CsdlAnnotation annotation(String term) throws ODataException {
+ CsdlSchema schema = provider.getSchemas().get(0);
+ assertNotNull(schema.getAnnotations());
+
+ return schema.getAnnotation(term);
+ }
+
+ @Test
+ public void testConstantExpressionAttribute() throws ODataException {
+ CsdlAnnotation a = annotation("Core.Description");
+ assertNotNull(a);
+ assertTrue(a.getExpression() instanceof CsdlConstantExpression);
+ assertEquals("Core terms needed to write vocabularies", ((CsdlConstantExpression)a.getExpression()).getValue());
+ assertEquals(ConstantExpressionType.String, ((CsdlConstantExpression)a.getExpression()).getType());
+
+ a = annotation("org.example.display.LastUpdated");
+ assertNotNull(a);
+ assertTrue(a.getExpression() instanceof CsdlConstantExpression);
+ assertEquals("2000-01-01T16:00:00.000-09:00", ((CsdlConstantExpression)a.getExpression()).getValue());
+ assertEquals(ConstantExpressionType.DateTimeOffset, ((CsdlConstantExpression)a.getExpression()).getType());
+ }
+
+ @Test
+ public void testCollection() throws ODataException {
+ CsdlAnnotation a = annotation("UI.CollectionFacet");
+ assertNotNull(a);
+ assertTrue(a.getExpression() instanceof CsdlCollection);
+ CsdlCollection exprs = ((CsdlCollection)a.getExpression());
+ assertEquals(2, exprs.getItems().size());
+ assertTrue(exprs.getItems().get(0) instanceof CsdlAnnotationPath);
+ CsdlAnnotationPath path = (CsdlAnnotationPath) exprs.getItems().get(0);
+ assertEquals("Supplier/@Communication.Contact", path.getValue());
+ }
+
+ @Test
+ public void testApply() throws ODataException {
+ CsdlAnnotation a = annotation("org.example.display.DisplayNameApply");
+ assertNotNull(a);
+ assertTrue(a.getExpression() instanceof CsdlApply);
+ CsdlApply apply = ((CsdlApply)a.getExpression());
+
+ assertEquals("odata.concat", apply.getFunction());
+ assertEquals(7, apply.getParameters().size());
+ assertTrue(apply.getParameters().get(1) instanceof CsdlPath);
+ assertTrue(apply.getParameters().get(4) instanceof CsdlConstantExpression);
+ }
+
+ @Test
+ public void testCast() throws ODataException {
+ CsdlAnnotation a = annotation("org.example.display.Threshold");
+ assertNotNull(a);
+ assertTrue(a.getExpression() instanceof CsdlCast);
+ CsdlCast cast= (CsdlCast)a.getExpression();
+
+ assertEquals("Edm.Decimal", cast.getType());
+ assertTrue(cast.getValue() instanceof CsdlPath);
+ assertEquals("Average", ((CsdlPath)cast.getValue()).getValue());
+ }
+
+ @Test
+ public void testIf() throws ODataException {
+ CsdlAnnotation a = annotation("org.example.person.Gender");
+ assertNotNull(a);
+ assertTrue(a.getExpression() instanceof CsdlIf);
+ CsdlIf ifexpr = (CsdlIf)a.getExpression();
+
+ assertTrue(ifexpr.getGuard() instanceof CsdlPath);
+ assertTrue(ifexpr.getThen() instanceof CsdlConstantExpression);
+ assertTrue(ifexpr.getElse() instanceof CsdlConstantExpression);
+
+ assertEquals("IsFemale", ((CsdlPath)ifexpr.getGuard()).getValue());
+ assertEquals("Female", ((CsdlConstantExpression)ifexpr.getThen()).getValue());
+ assertEquals("Male", ((CsdlConstantExpression)ifexpr.getElse()).getValue());
+ }
+
+ @Test
+ public void testIsOf() throws ODataException {
+ CsdlAnnotation a = annotation("Self.IsPreferredCustomer");
+ assertNotNull(a);
+ assertTrue(a.getExpression() instanceof CsdlIsOf);
+ CsdlIsOf isOf = (CsdlIsOf)a.getExpression();
+ assertEquals("Self.PreferredCustomer", isOf.getType());
+ assertTrue(isOf.getValue() instanceof CsdlPath);
+ }
+
+ @Test
+ public void testLableledElement() throws ODataException {
+ CsdlAnnotation a = annotation("org.example.display.DisplayNameLabel");
+ assertNotNull(a);
+ assertTrue(a.getExpression() instanceof CsdlLabeledElement);
+ CsdlLabeledElement expr = (CsdlLabeledElement)a.getExpression();
+ assertEquals("CustomerFirstName", expr.getName());
+ assertTrue(expr.getValue() instanceof CsdlPath);
+ }
+
+ @Test
+ public void testLableledReference() throws ODataException {
+ CsdlAnnotation a = annotation("org.example.display.DisplayNameLabelReference");
+ assertNotNull(a);
+ assertTrue(a.getExpression() instanceof CsdlLabeledElementReference);
+ CsdlLabeledElementReference expr = (CsdlLabeledElementReference)a.getExpression();
+ assertEquals("Model.CustomerFirstName", expr.getValue());
+ }
+
+ @Test
+ public void testNull() throws ODataException {
+ CsdlAnnotation a = annotation("org.example.display.DisplayNameNull");
+ assertNotNull(a);
+ assertTrue(a.getExpression() instanceof CsdlNull);
+ }
+
+ @Test
+ public void testRecord() throws ODataException {
+ CsdlAnnotation a = annotation("Capabilities.UpdateRestrictions");
+ assertNotNull(a);
+ assertTrue(a.getExpression() instanceof CsdlRecord);
+ CsdlRecord expr = (CsdlRecord)a.getExpression();
+ assertEquals(1, expr.getPropertyValues().size());
+ CsdlPropertyValue value = expr.getPropertyValues().get(0);
+ assertEquals("NonUpdatableNavigationProperties", value.getProperty());
+ assertTrue(value.getValue() instanceof CsdlCollection);
+
+ CsdlCollection collection = (CsdlCollection)value.getValue();
+ assertEquals(2, collection.getItems().size());
+ assertEquals("Category", ((CsdlNavigationPropertyPath)collection.getItems().get(1)).getValue());
+ }
+
+ @Test
+ public void testUrlRef() throws ODataException {
+ CsdlAnnotation a = annotation("Vocab.Supplier");
+ assertNotNull(a);
+ assertTrue(a.getExpression() instanceof CsdlUrlRef);
+ CsdlUrlRef expr = (CsdlUrlRef)a.getExpression();
+ assertTrue(expr.getValue() instanceof CsdlApply);
+ assertEquals(2, ((CsdlApply)expr.getValue()).getParameters().size());
+ }
+
+ @Test
+ public void testTermAppliesTo() throws ODataException {
+ CsdlTerm term = this.provider.getTerm(new FullQualifiedName(NS, "IsURI"));
+ assertEquals(Arrays.asList("Property", "PropertyPath"), term.getAppliesTo());
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6d94f0e3/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserTest.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserTest.java
index 5092357..97f19b5 100644
--- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserTest.java
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserTest.java
@@ -54,7 +54,8 @@ public class MetadataParserTest {
@Before
public void setUp() throws Exception {
MetadataParser parser = new MetadataParser();
- provider = parser.buildEdmProvider(new FileReader("src/test/resources/trippin.xml"));
+ parser.setParseAnnotations(true);
+ provider = (CsdlEdmProvider) parser.buildEdmProvider(new FileReader("src/test/resources/trippin.xml"));
}
@Test
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6d94f0e3/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/ServiceDispatcherTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/ServiceDispatcherTest.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/ServiceDispatcherTest.java
index a7fc922..90ead94 100644
--- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/ServiceDispatcherTest.java
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/ServiceDispatcherTest.java
@@ -26,7 +26,6 @@ import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.URI;
-import java.util.Collections;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
@@ -43,12 +42,10 @@ import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.olingo.commons.api.edm.provider.CsdlEdmProvider;
import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataHttpHandler;
import org.apache.olingo.server.api.ServiceMetadata;
-import org.apache.olingo.server.api.edmx.EdmxReference;
import org.apache.olingo.server.core.requests.ActionRequest;
import org.apache.olingo.server.core.requests.DataRequest;
import org.apache.olingo.server.core.requests.FunctionRequest;
@@ -73,20 +70,19 @@ public class ServiceDispatcherTest {
public class SampleODataServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private final ServiceHandler handler; // must be stateless
- private final CsdlEdmProvider provider; // must be stateless
+ private final ServiceMetadata metadata; // must be stateless
- public SampleODataServlet(ServiceHandler handler, CsdlEdmProvider provider) {
+ public SampleODataServlet(ServiceHandler handler, ServiceMetadata metadata) {
this.handler = handler;
- this.provider = provider;
+ this.metadata = metadata;
}
@Override
public void service(HttpServletRequest request, HttpServletResponse response)
throws IOException {
OData odata = OData4Impl.newInstance();
- ServiceMetadata metadata = odata.createServiceMetadata(this.provider, Collections.<EdmxReference> emptyList());
- ODataHttpHandler handler = odata.createHandler(metadata);
+ ODataHttpHandler handler = odata.createHandler(this.metadata);
handler.register(this.handler);
handler.process(request, response);
@@ -95,14 +91,13 @@ public class ServiceDispatcherTest {
public void beforeTest(ServiceHandler serviceHandler) throws Exception {
MetadataParser parser = new MetadataParser();
- CsdlEdmProvider edmProvider = parser.buildEdmProvider(new FileReader(
- "src/test/resources/trippin.xml"));
+ ServiceMetadata metadata = parser.buildServiceMetadata(new FileReader("src/test/resources/trippin.xml"));
File baseDir = new File(System.getProperty("java.io.tmpdir"));
tomcat.setBaseDir(baseDir.getAbsolutePath());
tomcat.getHost().setAppBase(baseDir.getAbsolutePath());
Context cxt = tomcat.addContext("/trippin", baseDir.getAbsolutePath());
- Tomcat.addServlet(cxt, "trippin", new SampleODataServlet(serviceHandler, edmProvider));
+ Tomcat.addServlet(cxt, "trippin", new SampleODataServlet(serviceHandler, metadata));
cxt.addServletMapping("/*", "trippin");
tomcat.setPort(TOMCAT_PORT);
tomcat.start();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6d94f0e3/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServlet.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServlet.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServlet.java
index fbc74ef..036cd78 100644
--- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServlet.java
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServlet.java
@@ -20,7 +20,6 @@ package org.apache.olingo.server.example;
import java.io.FileReader;
import java.io.IOException;
-import java.util.Collections;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
@@ -29,11 +28,9 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.stream.XMLStreamException;
-import org.apache.olingo.commons.api.edm.provider.CsdlEdmProvider;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataHttpHandler;
import org.apache.olingo.server.api.ServiceMetadata;
-import org.apache.olingo.server.api.edmx.EdmxReference;
import org.apache.olingo.server.core.MetadataParser;
import org.apache.olingo.server.core.OData4Impl;
@@ -50,16 +47,14 @@ public class TripPinServlet extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
OData odata = OData4Impl.newInstance();
MetadataParser parser = new MetadataParser();
- CsdlEdmProvider edmProvider = null;
+ ServiceMetadata metadata = null;
try {
- edmProvider = parser.buildEdmProvider(new FileReader("src/test/resources/trippin.xml"));
+ metadata = parser.buildServiceMetadata(new FileReader("src/test/resources/trippin.xml"));
} catch (XMLStreamException e) {
throw new IOException(e);
}
- ServiceMetadata metadata = odata.createServiceMetadata(edmProvider, Collections.<EdmxReference>emptyList());
-
ODataHttpHandler handler = odata.createHandler(metadata);
if (this.dataModel == null) {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6d94f0e3/lib/server-core-ext/src/test/resources/annotations.xml
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/resources/annotations.xml b/lib/server-core-ext/src/test/resources/annotations.xml
new file mode 100644
index 0000000..fce46a8
--- /dev/null
+++ b/lib/server-core-ext/src/test/resources/annotations.xml
@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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. -->
+<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
+ Version="4.0">
+ <edmx:DataServices>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm"
+ Namespace="Org.OData.Core.V1" Alias="Core">
+
+ <Annotation Term="Core.Description">
+ <String>Core terms needed to write vocabularies</String>
+ </Annotation>
+
+ <Annotation Term="org.example.display.Thumbnail">
+ <Binary>T0RhdGE</Binary>
+ </Annotation>
+
+ <Annotation Term="org.example.display.ReadOnly">
+ <Bool>true</Bool>
+ </Annotation>
+
+ <Annotation Term="org.example.display.LastUpdated"
+ DateTimeOffset="2000-01-01T16:00:00.000-09:00" />
+
+ <Annotation Term="UI.ReferenceFacet" AnnotationPath="Product/Supplier/@UI.LineItem" />
+
+ <Annotation Term="UI.CollectionFacet" Qualifier="Contacts">
+ <Collection>
+ <AnnotationPath>Supplier/@Communication.Contact</AnnotationPath>
+ <AnnotationPath>Customer/@Communication.Contact</AnnotationPath>
+ </Collection>
+ </Annotation>
+
+ <Annotation Term="org.example.display.DisplayNameApply">
+ <Apply Function="odata.concat">
+ <String>Product: </String>
+ <Path>ProductName</Path>
+ <String> (</String>
+ <Path>Available/Quantity</Path>
+ <String>
+ </String>
+ <Path>Available/Unit</Path>
+ <String> available)</String>
+ </Apply>
+ </Annotation>
+
+ <Annotation Term="org.example.display.Threshold">
+ <Cast Type="Edm.Decimal">
+ <Path>Average</Path>
+ </Cast>
+ </Annotation>
+ <Annotation Term="org.example.seo.SeoTerms">
+ <Collection>
+ <String>Product</String>
+ <String>Supplier</String>
+ <String>Customer</String>
+ </Collection>
+ </Annotation>
+
+ <Annotation Term="org.example.person.Gender">
+ <If>
+ <Path>IsFemale</Path>
+ <String>Female</String>
+ <String>Male</String>
+ </If>
+ </Annotation>
+
+ <Annotation Term="Self.IsPreferredCustomer">
+ <IsOf Type="Self.PreferredCustomer">
+ <Path>Customer</Path>
+ </IsOf>
+ </Annotation>
+
+ <Annotation Term="org.example.display.DisplayNameLabel">
+ <LabeledElement Name="CustomerFirstName">
+ <Path>FirstName</Path>
+ </LabeledElement>
+ </Annotation>
+
+ <Annotation Term="org.example.display.DisplayNameLabelReference">
+ <LabeledElementReference>Model.CustomerFirstName
+ </LabeledElementReference>
+ </Annotation>
+
+ <Annotation Term="org.example.display.DisplayNameNull">
+ <Null />
+ </Annotation>
+
+ <Annotation Term="Capabilities.UpdateRestrictions">
+ <Record>
+ <PropertyValue Property="NonUpdatableNavigationProperties">
+ <Collection>
+ <NavigationPropertyPath>Supplier</NavigationPropertyPath>
+ <NavigationPropertyPath>Category</NavigationPropertyPath>
+ </Collection>
+ </PropertyValue>
+ </Record>
+ </Annotation>
+
+ <Annotation Term="org.example.display.DisplayNamePath">
+ <Path>@vCard.Address#work/FullName</Path>
+ </Annotation>
+
+ <Term Name="IsURI" Type="Core.Tag" DefaultValue="true"
+ AppliesTo="Property PropertyPath">
+ <Annotation Term="Core.Description">
+ <String>
+ Properties and terms annotated with this term MUST contain a valid URI
+ </String>
+ </Annotation>
+ <Annotation Term="Core.RequiresType" String="Edm.String" />
+ </Term>
+
+ <Annotation Term="org.example.person.Employee">
+ <Record>
+ <PropertyValue Property="GivenName" Path="FirstName" />
+ <PropertyValue Property="Surname" Path="LastName" />
+ <PropertyValue Property="Manager" Path="DirectSupervisor" />
+ <PropertyValue Property="CostCenter">
+ <UrlRef>
+ <Apply Function="odata.fillUriTemplate">
+ <String>http://host/anotherservice/CostCenters('{ccid}')
+ </String>
+ <LabeledElement Name="ccid" Path="CostCenterID" />
+ </Apply>
+ </UrlRef>
+ </PropertyValue>
+ </Record>
+ </Annotation>
+
+ <Annotation Term="Vocab.Supplier">
+ <UrlRef>
+ <Apply Function="odata.fillUriTemplate">
+ <String>http://host/service/Suppliers({suppID})</String>
+ <LabeledElement Name="suppID">
+ <Apply Function="odata.uriEncode">
+ <Path>SupplierId</Path>
+ </Apply>
+ </LabeledElement>
+ </Apply>
+ </UrlRef>
+ </Annotation>
+ </Schema>
+ </edmx:DataServices>
+</edmx:Edmx>
\ No newline at end of file
[10/22] olingo-odata4 git commit: [OLINGO-852] less warnings +
general clean-up
Posted by mi...@apache.org.
[OLINGO-852] less warnings + general clean-up
Signed-off-by: Christian Amend <ch...@sap.com>
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/5d7c1287
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/5d7c1287
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/5d7c1287
Branch: refs/heads/OLINGO-832_StreamSerializerPoC
Commit: 5d7c1287f042fbb6c50e815c2dc1af9903b74951
Parents: 110c7b0
Author: Klaus Straubinger <kl...@sap.com>
Authored: Thu Feb 4 12:28:35 2016 +0100
Committer: Christian Amend <ch...@sap.com>
Committed: Thu Feb 4 12:42:29 2016 +0100
----------------------------------------------------------------------
.../commons/AbstractInvocationHandler.java | 17 +-
.../AbstractStructuredInvocationHandler.java | 2 +-
.../commons/AnnotatationsInvocationHandler.java | 2 +-
.../ComplexCollectionInvocationHandler.java | 2 +-
.../proxy/commons/ComplexInvocationHandler.java | 6 +-
.../proxy/commons/EdmStreamValueHandler.java | 2 +-
.../EntityCollectionInvocationHandler.java | 2 +-
.../EntityContainerInvocationHandler.java | 4 +-
.../proxy/commons/EntityInvocationHandler.java | 6 +-
.../commons/EntitySetInvocationHandler.java | 2 +-
.../proxy/commons/InvokerInvocationHandler.java | 2 +-
.../commons/OperationInvocationHandler.java | 2 +-
.../PrimitiveCollectionInvocationHandler.java | 2 +-
...turedComposableInvokerInvocationHandler.java | 2 +-
.../olingo/ext/proxy/utils/CoreUtils.java | 5 +-
.../org/apache/olingo/fit/AbstractServices.java | 1947 --------------
.../main/java/org/apache/olingo/fit/Demo.java | 6 +-
.../java/org/apache/olingo/fit/OpenType.java | 5 +-
.../java/org/apache/olingo/fit/Services.java | 2511 +++++++++++++++---
.../org/apache/olingo/fit/Vocabularies.java | 10 +-
.../apache/olingo/fit/metadata/EntitySet.java | 8 -
.../olingo/fit/rest/OAuth2RequestFilter.java | 3 +-
.../fit/serializer/FITAtomDeserializer.java | 13 +-
.../olingo/fit/utils/AbstractUtilities.java | 22 +-
.../org/apache/olingo/fit/utils/Accept.java | 31 +-
.../org/apache/olingo/fit/utils/Commons.java | 24 +-
.../apache/olingo/fit/utils/ConstantKey.java | 10 +-
.../org/apache/olingo/fit/utils/Constants.java | 7 -
.../org/apache/olingo/fit/utils/FSManager.java | 25 +-
.../fit/utils/InjectableSerializerProvider.java | 42 -
.../apache/olingo/fit/utils/JSONUtilities.java | 14 +-
.../olingo/fit/utils/MetadataLinkInfo.java | 182 --
.../apache/olingo/fit/utils/XMLUtilities.java | 3 +
.../proxy/demo/odatademo/types/Customer.java | 6 +-
.../proxy/demo/odatademo/types/Employee.java | 6 +-
.../demo/odatademo/types/FeaturedProduct.java | 6 +-
.../opentypesservice/types/IndexedRow.java | 8 +-
.../odatawcfservice/types/CreditCardPI.java | 6 +-
.../odatawcfservice/types/Customer.java | 6 +-
.../odatawcfservice/types/Employee.java | 6 +-
.../odatawcfservice/types/PublicCompany.java | 8 +-
.../tecsvc/client/EntityReferencesITCase.java | 13 +-
.../ExpandWithSystemQueryOptionsITCase.java | 74 +-
.../core/domain/AbstractClientEntitySet.java | 114 -
.../core/domain/ClientCollectionValueImpl.java | 2 +-
.../client/core/domain/ClientEntitySetImpl.java | 74 +-
.../core/domain/ClientPrimitiveValueImpl.java | 5 +-
.../client/core/domain/ClientPropertyImpl.java | 135 +-
.../client/core/domain/ClientValuableImpl.java | 22 +-
.../core/serialization/ODataBinderImpl.java | 2 +-
.../apache/olingo/client/core/AbstractTest.java | 9 +-
.../org/apache/olingo/client/core/AtomTest.java | 6 -
.../olingo/client/core/EntitySetTest.java | 22 +-
.../apache/olingo/client/core/EntityTest.java | 73 +-
.../apache/olingo/client/core/ErrorTest.java | 8 +-
.../org/apache/olingo/client/core/JSONTest.java | 46 +-
.../apache/olingo/client/core/MetadataTest.java | 33 +-
.../olingo/client/core/PrimitiveValueTest.java | 22 +-
.../apache/olingo/client/core/PropertyTest.java | 38 +-
.../olingo/client/core/ServiceDocumentTest.java | 16 +-
.../client/core/uri/FilterFactoryTest.java | 8 +-
.../olingo/client/core/uri/URIBuilderTest.java | 71 +-
.../olingo/commons/api/edm/geo/Geospatial.java | 7 +-
.../core/edm/EdmNavigationPropertyImpl.java | 3 +-
.../commons/core/edm/EdmParameterImpl.java | 3 +-
.../commons/core/edm/EdmPropertyImpl.java | 5 +-
.../core/batchhandler/BatchFacadeImpl.java | 18 +-
.../server/core/batchhandler/BatchHandler.java | 2 +-
68 files changed, 2488 insertions(+), 3316 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractInvocationHandler.java
index 258a496..ff4663e 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractInvocationHandler.java
@@ -69,7 +69,7 @@ abstract class AbstractInvocationHandler implements InvocationHandler {
return service.getContext();
}
- protected boolean isSelfMethod(final Method method, final Object[] args) {
+ protected boolean isSelfMethod(final Method method) {
final Method[] selfMethods = getClass().getMethods();
boolean result = false;
@@ -161,7 +161,7 @@ abstract class AbstractInvocationHandler implements InvocationHandler {
CoreUtils.addProperties(getClient(), handler.getPropertyChanges(), template);
final Object key = CoreUtils.getKey(getClient(), handler, handler.getUUID().getType(), template);
- entityURI = CoreUtils.buildEditLink(getClient(), baseURI.toASCIIString(), template, key).build();
+ entityURI = CoreUtils.buildEditLink(getClient(), baseURI.toASCIIString(), key).build();
template.setEditLink(entityURI);
} else {
entityURI = handler.getEntityURI();
@@ -182,32 +182,25 @@ abstract class AbstractInvocationHandler implements InvocationHandler {
}
}
- protected static URIBuilder buildEntitySetURI(
- final Class<?> ref,
- final AbstractService<?> service) {
+ protected static URIBuilder buildEntitySetURI(final Class<?> ref, final AbstractService<?> service) {
- final String containerNS;
final String entitySetName;
Annotation ann = ref.getAnnotation(EntitySet.class);
if (ann instanceof EntitySet) {
- containerNS = EntitySet.class.cast(ann).container();
entitySetName = EntitySet.class.cast(ann).name();
} else {
ann = ref.getAnnotation(Singleton.class);
if (ann instanceof Singleton) {
- containerNS = Singleton.class.cast(ann).container();
entitySetName = Singleton.class.cast(ann).name();
} else {
- containerNS = null;
entitySetName = null;
}
}
- return buildEntitySetURI(containerNS, entitySetName, service);
+ return buildEntitySetURI(entitySetName, service);
}
- protected static URIBuilder buildEntitySetURI(
- final String containerNS, final String entitySetName, final AbstractService<?> service) {
+ protected static URIBuilder buildEntitySetURI(final String entitySetName, final AbstractService<?> service) {
final URIBuilder uriBuilder = service.getClient().newURIBuilder();
final StringBuilder entitySetSegment = new StringBuilder();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractStructuredInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractStructuredInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractStructuredInvocationHandler.java
index 96b3f26..a448186 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractStructuredInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractStructuredInvocationHandler.java
@@ -210,7 +210,7 @@ public abstract class AbstractStructuredInvocationHandler extends AbstractInvoca
|| "refs".equals(method.getName())) {
invokeSelfMethod(method, args);
return proxy;
- } else if (isSelfMethod(method, args)) {
+ } else if (isSelfMethod(method)) {
return invokeSelfMethod(method, args);
} else if ("load".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
load();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AnnotatationsInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AnnotatationsInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AnnotatationsInvocationHandler.java
index fcd5078..8f0951d 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AnnotatationsInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AnnotatationsInvocationHandler.java
@@ -55,7 +55,7 @@ public class AnnotatationsInvocationHandler extends AbstractInvocationHandler {
@Override
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
- if (isSelfMethod(method, args)) {
+ if (isSelfMethod(method)) {
return invokeSelfMethod(method, args);
} else if (method.getName().startsWith("get") && method.getName().endsWith("Annotations")) {
final Method getter = proxy.getClass().getInterfaces()[0].getMethod(method.getName());
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexCollectionInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexCollectionInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexCollectionInvocationHandler.java
index ff4fc66..8699ed4 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexCollectionInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexCollectionInvocationHandler.java
@@ -80,7 +80,7 @@ public class ComplexCollectionInvocationHandler<T extends ComplexType<?>>
invokeSelfMethod(method, args);
return proxy;
- } else if (isSelfMethod(method, args)) {
+ } else if (isSelfMethod(method)) {
return invokeSelfMethod(method, args);
} else if ("operations".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
final Class<?> returnType = method.getReturnType();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexInvocationHandler.java
index 3aa3326..1e2197c 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexInvocationHandler.java
@@ -63,11 +63,7 @@ public class ComplexInvocationHandler extends AbstractStructuredInvocationHandle
return new ImmutablePair<ClientComplexValue, Class<?>>(complex, complexTypeRef);
}
- public static ComplexInvocationHandler getInstance(
- final String propertyName,
- final EntityInvocationHandler handler,
- final Class<?> typeRef) {
-
+ public static ComplexInvocationHandler getInstance(final EntityInvocationHandler handler, final Class<?> typeRef) {
final Pair<ClientComplexValue, Class<?>> init = init(typeRef, handler.service);
return new ComplexInvocationHandler(init.getLeft(), init.getRight(), handler);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EdmStreamValueHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EdmStreamValueHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EdmStreamValueHandler.java
index d197f58..c13a3cf 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EdmStreamValueHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EdmStreamValueHandler.java
@@ -59,7 +59,7 @@ public class EdmStreamValueHandler extends AbstractInvocationHandler {
load();
return proxy;
} else {
- if (isSelfMethod(method, args)) {
+ if (isSelfMethod(method)) {
return invokeSelfMethod(method, args);
} else {
throw new NoSuchMethodException(method.getName());
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityCollectionInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityCollectionInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityCollectionInvocationHandler.java
index 5c8da2c..e7d819a 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityCollectionInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityCollectionInvocationHandler.java
@@ -62,7 +62,7 @@ public class EntityCollectionInvocationHandler<T extends EntityType<?>>
|| "execute".equals(method.getName())) {
invokeSelfMethod(method, args);
return proxy;
- } else if (isSelfMethod(method, args)) {
+ } else if (isSelfMethod(method)) {
return invokeSelfMethod(method, args);
} else if ("operations".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
final Class<?> returnType = method.getReturnType();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityContainerInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityContainerInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityContainerInvocationHandler.java
index cb72126..af8101b 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityContainerInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityContainerInvocationHandler.java
@@ -80,7 +80,7 @@ public final class EntityContainerInvocationHandler extends AbstractInvocationHa
@Override
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
- if (isSelfMethod(method, args)) {
+ if (isSelfMethod(method)) {
return invokeSelfMethod(method, args);
} else if ("flush".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
service.getPersistenceManager().flush();
@@ -114,7 +114,7 @@ public final class EntityContainerInvocationHandler extends AbstractInvocationHa
final Class<?> typeRef = method.getReturnType();
final Singleton singleton = method.getAnnotation(Singleton.class);
- final URI uri = buildEntitySetURI(singleton.container(), singleton.name(), service).build();
+ final URI uri = buildEntitySetURI(singleton.name(), service).build();
final EntityUUID uuid = new EntityUUID(uri, typeRef);
LOG.debug("Ask for singleton '{}'", typeRef.getSimpleName());
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityInvocationHandler.java
index c124402..e993140 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityInvocationHandler.java
@@ -191,7 +191,7 @@ public class EntityInvocationHandler extends AbstractStructuredInvocationHandler
this.uri = getClient().newURIBuilder(baseURI.toASCIIString());
} else if (key != null) {
final URIBuilder uriBuilder =
- CoreUtils.buildEditLink(getClient(), entitySetURI.toASCIIString(), entity, key);
+ CoreUtils.buildEditLink(getClient(), entitySetURI.toASCIIString(), key);
this.uri = uriBuilder;
this.baseURI = this.uri.build();
@@ -219,7 +219,7 @@ public class EntityInvocationHandler extends AbstractStructuredInvocationHandler
if (this.uri == null) {
final URIBuilder uriBuilder =
entity.getEditLink() == null
- ? CoreUtils.buildEditLink(getClient(), getUUID().getEntitySetURI().toASCIIString(), entity, key)
+ ? CoreUtils.buildEditLink(getClient(), getUUID().getEntitySetURI().toASCIIString(), key)
: getClient().newURIBuilder(entity.getEditLink().toASCIIString());
this.uri = uriBuilder;
@@ -252,7 +252,7 @@ public class EntityInvocationHandler extends AbstractStructuredInvocationHandler
if (this.uri == null) {
final URIBuilder uriBuilder =
getEntity().getEditLink() == null
- ? CoreUtils.buildEditLink(getClient(), entitySetURI.toASCIIString(), getEntity(), key)
+ ? CoreUtils.buildEditLink(getClient(), entitySetURI.toASCIIString(), key)
: getClient().newURIBuilder(getEntity().getEditLink().toASCIIString());
this.uri = uriBuilder;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntitySetInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntitySetInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntitySetInvocationHandler.java
index 8250f72..9d1970a 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntitySetInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntitySetInvocationHandler.java
@@ -84,7 +84,7 @@ public class EntitySetInvocationHandler<
invokeSelfMethod(method, args);
return proxy;
- } else if (isSelfMethod(method, args)) {
+ } else if (isSelfMethod(method)) {
return invokeSelfMethod(method, args);
} else {
throw new NoSuchMethodException(method.getName());
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/InvokerInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/InvokerInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/InvokerInvocationHandler.java
index 53208f7..3ed6121 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/InvokerInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/InvokerInvocationHandler.java
@@ -276,7 +276,7 @@ public class InvokerInvocationHandler<T, O extends Operations> extends AbstractI
return Proxy.newProxyInstance(
Thread.currentThread().getContextClassLoader(),
new Class<?>[] {operationRef}, handler);
- } else if (isSelfMethod(method, args)) {
+ } else if (isSelfMethod(method)) {
return invokeSelfMethod(method, args);
} else {
throw new NoSuchMethodException(method.getName());
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/OperationInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/OperationInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/OperationInvocationHandler.java
index bdab06c..23cd25c 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/OperationInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/OperationInvocationHandler.java
@@ -133,7 +133,7 @@ final class OperationInvocationHandler extends AbstractInvocationHandler {
@Override
@SuppressWarnings({"unchecked", "rawtypes"})
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
- if (isSelfMethod(method, args)) {
+ if (isSelfMethod(method)) {
return invokeSelfMethod(method, args);
} else {
final Operation operation = method.getAnnotation(Operation.class);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/PrimitiveCollectionInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/PrimitiveCollectionInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/PrimitiveCollectionInvocationHandler.java
index 553af6e..67d6e86 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/PrimitiveCollectionInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/PrimitiveCollectionInvocationHandler.java
@@ -75,7 +75,7 @@ public class PrimitiveCollectionInvocationHandler<T extends Serializable>
invokeSelfMethod(method, args);
return proxy;
- } else if (isSelfMethod(method, args)) {
+ } else if (isSelfMethod(method)) {
return invokeSelfMethod(method, args);
} else if ("operations".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
final Class<?> returnType = method.getReturnType();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/StructuredComposableInvokerInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/StructuredComposableInvokerInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/StructuredComposableInvokerInvocationHandler.java
index 41ec9ce..00670b3 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/StructuredComposableInvokerInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/StructuredComposableInvokerInvocationHandler.java
@@ -75,7 +75,7 @@ public class StructuredComposableInvokerInvocationHandler<T, O extends Operation
return super.invoke(proxy, method, args);
} else if ("operations".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
return super.invoke(proxy, method, args);
- } else if (isSelfMethod(method, args)) {
+ } else if (isSelfMethod(method)) {
return invokeSelfMethod(method, args);
} else {
throw new NoSuchMethodException(method.getName());
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
index 2776f3b..8f804fe 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
@@ -378,7 +378,6 @@ public final class CoreUtils {
public static URIBuilder buildEditLink(
final EdmEnabledODataClient client,
final String entitySetURI,
- final ClientEntity entity,
final Object key) {
if (key == null) {
@@ -506,7 +505,7 @@ public final class CoreUtils {
final Object complex = Proxy.newProxyInstance(
Thread.currentThread().getContextClassLoader(),
new Class<?>[] { getter.getReturnType() },
- ComplexInvocationHandler.getInstance(property.getName(), typeHandler, getter.getReturnType()));
+ ComplexInvocationHandler.getInstance(typeHandler, getter.getReturnType()));
populate(client, typeHandler, complex, Property.class, property.getValue().asComplex().iterator());
setPropertyValue(bean, getter, complex);
@@ -530,7 +529,7 @@ public final class CoreUtils {
final Object collItem = Proxy.newProxyInstance(
Thread.currentThread().getContextClassLoader(),
new Class<?>[] { collItemClass },
- ComplexInvocationHandler.getInstance(property.getName(), typeHandler, collItemClass));
+ ComplexInvocationHandler.getInstance(typeHandler, collItemClass));
populate(client, typeHandler, collItem, Property.class, value.asComplex().iterator());
collection.add(collItem);
[03/22] olingo-odata4 git commit: OLINGO-864: Refining the Edm.Date
and Edm.Time behavior not to assume GMT
Posted by mi...@apache.org.
OLINGO-864: Refining the Edm.Date and Edm.Time behavior not to assume GMT
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/f63bba70
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/f63bba70
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/f63bba70
Branch: refs/heads/OLINGO-832_StreamSerializerPoC
Commit: f63bba70ad4c63a621b5a8e8186d50c172263989
Parents: b317b90 382ec16
Author: Ramesh Reddy <ra...@jboss.org>
Authored: Wed Feb 3 11:48:04 2016 -0600
Committer: Ramesh Reddy <ra...@jboss.org>
Committed: Wed Feb 3 11:48:04 2016 -0600
----------------------------------------------------------------------
.../client/AbstractParamTecSvcITCase.java | 14 ++++
.../commons/core/edm/primitivetype/EdmDate.java | 5 +-
.../edm/primitivetype/EdmDateTimeOffset.java | 75 +++++++++++++-------
.../core/edm/primitivetype/EdmTimeOfDay.java | 20 ++----
.../core/edm/primitivetype/EdmDateTest.java | 1 -
.../primitivetype/EdmDateTimeOffsetTest.java | 9 ++-
.../edm/primitivetype/EdmTimeOfDayTest.java | 23 ++++--
.../olingo/server/tecsvc/data/DataProvider.java | 6 ++
.../server/tecsvc/data/DataProviderTest.java | 14 ++++
9 files changed, 115 insertions(+), 52 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f63bba70/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AbstractParamTecSvcITCase.java
----------------------------------------------------------------------
diff --cc fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AbstractParamTecSvcITCase.java
index d6e35a3,0000000..a4d8a67
mode 100644,000000..100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AbstractParamTecSvcITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AbstractParamTecSvcITCase.java
@@@ -1,66 -1,0 +1,80 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.fit.tecsvc.client;
+
+import static org.hamcrest.CoreMatchers.startsWith;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.List;
++import java.util.TimeZone;
+
+import org.apache.olingo.commons.api.format.ContentType;
++import org.apache.olingo.server.tecsvc.data.DataProvider;
++import org.junit.After;
++import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public abstract class AbstractParamTecSvcITCase extends AbstractTecSvcITCase {
+
+ @Parameterized.Parameter
+ public ContentType contentType;
+
+ /**
+ * Returns a list of parameter arrays, in this case a list of one-element arrays
+ * containing the content types to be used.
+ */
+ @Parameterized.Parameters(name = "{0}")
+ public static List<ContentType[]> parameters() {
+ return Arrays.asList(new ContentType[] { ContentType.APPLICATION_JSON },
+ new ContentType[] { ContentType.APPLICATION_XML });
+ }
+
+ @Override
+ protected ContentType getContentType() {
+ return contentType;
+ }
+
+ protected void assertContentType(final String content) {
+ assertThat(content, startsWith(contentType.toContentTypeString()));
+ }
+
+ protected boolean isJson() {
+ return ContentType.JSON.isCompatible(contentType);
+ }
+
+ protected void assertShortOrInt(final int value, final Object n) {
+ assertTrue(n instanceof Number);
+ assertEquals(value, ((Number) n).intValue());
+ }
++
++ @Before
++ public void setup() {
++ DataProvider.setDefaultTimeZone("GMT");
++ }
++
++ @After
++ public void teardown() {
++ DataProvider.setDefaultTimeZone(TimeZone.getDefault().getID());
++ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f63bba70/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDate.java
----------------------------------------------------------------------
diff --cc lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDate.java
index 3eddca0,fb3f4ad..8588a5c
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDate.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDate.java
@@@ -18,8 -18,9 +18,7 @@@
*/
package org.apache.olingo.commons.core.edm.primitivetype;
-import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
-
import java.util.Calendar;
- import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f63bba70/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java
----------------------------------------------------------------------
diff --cc lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java
index a7f57d1,95b0fa5..63c2c3c
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java
@@@ -18,16 -18,17 +18,17 @@@
*/
package org.apache.olingo.commons.core.edm.primitivetype;
+ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
+
import java.sql.Time;
import java.sql.Timestamp;
-import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
- import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
+
/**
* Implementation of the EDM primitive type DateTimeOffset.
*/
@@@ -60,8 -68,8 +61,9 @@@ public final class EdmDateTimeOffset ex
}
final String timeZoneOffset = matcher.group(9) == null || matcher.group(10) == null
- || matcher.group(10).matches("[-+]0+:0+") ? null : matcher.group(10);
- final Calendar dateTimeValue = Calendar.getInstance(TimeZone.getTimeZone("GMT" + timeZoneOffset));
+ || matcher.group(10).matches("[-+]0+:0+") ? null : matcher.group(10);
- final Calendar dateTimeValue = Calendar.getInstance(TimeZone.getTimeZone("GMT" + timeZoneOffset));
++ final TimeZone tz = TimeZone.getTimeZone("GMT" + ((timeZoneOffset == null) ? "" : timeZoneOffset));
++ final Calendar dateTimeValue = Calendar.getInstance(tz);
if (dateTimeValue.get(Calendar.ZONE_OFFSET) == 0 && timeZoneOffset != null) {
throw new EdmPrimitiveTypeException("The literal '" + value + "' has illegal content.");
}
@@@ -150,19 -170,12 +165,12 @@@
@Override
protected <T> String internalValueToString(final T value,
- final Boolean isNullable, final Integer maxLength, final Integer precision,
- final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
- Calendar dateTimeValue;
- if (value instanceof Timestamp) {
- final Calendar tmp = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
- tmp.setTimeInMillis(((Timestamp) value).getTime());
- dateTimeValue = createDateTime(tmp);
- } else {
- dateTimeValue = createDateTime(value);
- }
-
- StringBuilder result = new StringBuilder();
+ final Calendar dateTimeValue = createDateTime(value, false);
+
+ final StringBuilder result = new StringBuilder();
final int year = dateTimeValue.get(Calendar.YEAR);
appendTwoDigits(result, year / 100);
appendTwoDigits(result, year % 100);
@@@ -269,4 -286,49 +283,17 @@@
}
}
}
+
+ /**
- * Appends the given fractional seconds to the given string builder.
- *
- * @param result a {@link StringBuilder}
- * @param fractionalSeconds fractional seconds
- * @param precision the upper limit for decimal digits (optional, defaults to zero)
- * @throws IllegalArgumentException if precision is not met
- */
- protected static void appendFractionalSeconds(final StringBuilder result, final int fractionalSeconds,
- final Integer precision) throws IllegalArgumentException {
-
- if (fractionalSeconds > 0) {
- String formatted = NANO_FORMAT.get().format(fractionalSeconds);
- int actualLength = formatted.length();
- boolean nonZeroFound = false;
- for (int i = formatted.length() - 1; i >= 0 && !nonZeroFound; i--) {
- if ('0' == formatted.charAt(i)) {
- actualLength--;
- } else {
- nonZeroFound = true;
- }
- }
-
- if (precision == null || precision < actualLength) {
- throw new IllegalArgumentException();
- }
-
- result.append('.').append(formatted.substring(0, actualLength));
- }
- }
-
- /**
+ * When the Timezone information is absent on the date time types, like EdmDate, EDMTimeOfDay, EdmDateTimeOffset
+ * this method defines the default timezone that should be used parse and output payload.
+ * User should set system property "defaultTimeZoneForEdmDateTypes" to control this. The default would be
+ * Java VM default if not defined.
+ *
+ * @return Timezone
+ */
+ protected static TimeZone getDefaultTimeZone() {
+ String tz = System.getProperty("defaultTimeZoneForEdmDateTypes");
- return (tz != null)?TimeZone.getTimeZone(tz):TimeZone.getDefault();
- }
-
++ return (tz != null)?TimeZone.getTimeZone(tz):TimeZone.getDefault();
++ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f63bba70/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java
----------------------------------------------------------------------
diff --cc lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java
index 7595e51,3090761..06ba239
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java
@@@ -18,9 -18,10 +18,8 @@@
*/
package org.apache.olingo.commons.core.edm.primitivetype;
-import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
-
import java.sql.Timestamp;
import java.util.Calendar;
- import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@@ -112,7 -101,13 +101,8 @@@ public final class EdmTimeOfDay extend
EdmDateTimeOffset.appendTwoDigits(result, dateTimeValue.get(Calendar.SECOND));
try {
- EdmDateTimeOffset.appendFractionalSeconds(result, fractionalSecs, value instanceof Timestamp, precision);
- if (value instanceof Timestamp) {
- int fractionalSecs = ((Timestamp) value).getNanos();
- EdmDateTimeOffset.appendFractionalSeconds(result, fractionalSecs, precision);
- } else {
- int fractionalSecs = dateTimeValue.get(Calendar.MILLISECOND);
- EdmDateTimeOffset.appendMilliseconds(result, fractionalSecs, precision);
- }
++ EdmDateTimeOffset.appendFractionalSeconds(result,
++ dateTimeValue.get(Calendar.MILLISECOND), value instanceof Timestamp, precision);
} catch (final IllegalArgumentException e) {
throw new EdmPrimitiveTypeException("The value '" + value + "' does not match the facets' constraints.", e);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f63bba70/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f63bba70/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java
----------------------------------------------------------------------
diff --cc lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java
index a352703,0b51925..5f2da25
--- a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java
+++ b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java
@@@ -18,10 -18,10 +18,9 @@@
*/
package org.apache.olingo.commons.core.edm.primitivetype;
-import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
-import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
-import org.junit.Test;
+import static org.junit.Assert.assertEquals;
- import static org.junit.Assert.assertTrue;
+import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
@@@ -76,22 -74,12 +75,21 @@@ public class EdmDateTimeOffsetTest exte
assertEquals("2012-02-29T23:32:03.007Z", instance.valueToString(millis, null, null, 3, null, null));
assertEquals("1969-12-31T23:59:59.9Z", instance.valueToString(-100L, null, null, 1, null, null));
assertEquals("1969-12-31T23:59:59.98Z", instance.valueToString(-20L, null, null, 2, null, null));
-
+
+ assertEquals("2012-02-29T23:32:03.007Z", instance.valueToString(new Time(millis), null, null, 3, null, null));
+ assertEquals("1969-12-31T23:59:59.9Z", instance.valueToString(new Time(-100L), null, null, 1, null, null));
+ assertEquals("1969-12-31T23:59:59.98Z", instance.valueToString(new Time(-20L), null, null, 2, null, null));
+
final Date date = new Date(millis);
- final String time = date.toString().substring(11, 19);
- assertTrue(instance.valueToString(date, null, null, 3, null, null).contains(time));
+ assertEquals("2012-02-29T23:32:03.007Z", instance.valueToString(date, null, null, 3, null, null));
+ Timestamp timestamp = new Timestamp(0);
+ timestamp.setNanos(120);
+ assertEquals("1970-01-01T00:00:00.00000012Z", instance.valueToString(timestamp, null, null, 8, null, null));
+
expectFacetsErrorInValueToString(instance, millis, null, null, null, null, null);
expectFacetsErrorInValueToString(instance, 3L, null, null, 2, null, null);
+ expectFacetsErrorInValueToString(instance, timestamp, null, null, 7, null, null);
expectTypeErrorInValueToString(instance, 0);
}
@@@ -133,14 -121,7 +131,15 @@@
Long.class));
assertEquals(Long.valueOf(120L), instance.valueOfString("1970-01-01T00:00:00.12", null, null, 2, null, null,
Long.class));
-
+
+ assertEquals(new Time(120000L), instance.valueOfString("1970-01-01T00:02", null, null, null, null, null,
+ Time.class));
- assertEquals(new Time(12L), instance.valueOfString("1970-01-01T00:00:00.012", null, null, 3, null, null,
++ // 0L because java.sql.Time does not keep track of fraction of milliseconds
++ assertEquals(new Time(0L), instance.valueOfString("1970-01-01T00:00:00.012", null, null, 3, null, null,
+ Time.class));
- assertEquals(new Time(120L), instance.valueOfString("1970-01-01T00:00:00.12", null, null, 2, null, null,
++ assertEquals(new Time(0L), instance.valueOfString("1970-01-01T00:00:00.12", null, null, 2, null, null,
+ Time.class));
+
expectFacetsErrorInValueOfString(instance, "2012-02-29T23:32:02.9Z", null, null, null, null, null);
expectFacetsErrorInValueOfString(instance, "2012-02-29T23:32:02.9Z", null, null, 0, null, null);
expectContentErrorInValueOfString(instance, "2012-02-29T23:32:02X");
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f63bba70/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDayTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f63bba70/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java
----------------------------------------------------------------------
diff --cc lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java
index 20cbf94,878efce..5190c71
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java
@@@ -512,151 -473,55 +512,157 @@@ public class DataProvider
entity.getProperties().remove(entity.getProperty(MEDIA_PROPERTY_NAME));
entity.addProperty(DataCreator.createPrimitive(MEDIA_PROPERTY_NAME, media));
entity.setMediaContentType(type);
+ entity.setMediaETag("W/\"" + UUID.randomUUID() + "\"");
+ }
+
+ public EntityCollection readFunctionEntityCollection(final EdmFunction function, final List<UriParameter> parameters,
+ final UriInfoResource uriInfo) throws DataProviderException {
+ return FunctionData.entityCollectionFunction(function.getName(),
+ getFunctionParameters(function, parameters, uriInfo),
+ data);
+ }
+
+ public Entity readFunctionEntity(final EdmFunction function, final List<UriParameter> parameters,
+ final UriInfoResource uriInfo) throws DataProviderException {
+ return FunctionData.entityFunction(function.getName(),
+ getFunctionParameters(function, parameters, uriInfo),
+ data);
+ }
+
+ public Property readFunctionPrimitiveComplex(final EdmFunction function, final List<UriParameter> parameters,
+ final UriInfoResource uriInfo) throws DataProviderException {
+ return FunctionData.primitiveComplexFunction(function.getName(),
+ getFunctionParameters(function, parameters, uriInfo),
+ data);
+ }
+
+ private Map<String, Parameter> getFunctionParameters(final EdmFunction function,
+ final List<UriParameter> parameters, final UriInfoResource uriInfo) throws DataProviderException {
+ Map<String, Parameter> values = new HashMap<String, Parameter>();
+ for (final UriParameter parameter : parameters) {
+ final EdmParameter edmParameter = function.getParameter(parameter.getName());
+ final String text = parameter.getAlias() == null ?
+ parameter.getText() :
+ uriInfo.getValueForAlias(parameter.getAlias());
+ if (text != null) {
+ try {
+ values.put(parameter.getName(),
+ odata.createFixedFormatDeserializer().parameter(text, edmParameter));
+ } catch (final DeserializerException e) {
+ throw new DataProviderException("Invalid function parameter.", HttpStatusCode.BAD_REQUEST, e);
+ }
+ }
+ }
+ return values;
}
- public EntityCollection readFunctionEntitySet(final EdmFunction function, final List<UriParameter> parameters)
+ public Property processActionPrimitive(final String name, final Map<String, Parameter> actionParameters)
throws DataProviderException {
- return FunctionData.entityCollectionFunction(function.getName(), parameters, data);
+ return ActionData.primitiveAction(name, actionParameters);
}
- public Entity readFunctionEntity(final EdmFunction function, final List<UriParameter> parameters)
+ public Property processActionComplex(final String name, final Map<String, Parameter> actionParameters)
throws DataProviderException {
- return FunctionData.entityFunction(function.getName(), parameters, data);
+ return ActionData.complexAction(name, actionParameters);
}
- public Property readFunctionPrimitiveComplex(final EdmFunction function, final List<UriParameter> parameters)
+ public Property processActionComplexCollection(final String name, final Map<String, Parameter> actionParameters)
throws DataProviderException {
- return FunctionData.primitiveComplexFunction(function.getName(), parameters, data);
+ return ActionData.complexCollectionAction(name, actionParameters);
}
- public Property processActionPrimitive(String name, Map<String, Parameter> actionParameters)
+ public Property processActionPrimitiveCollection(final String name, final Map<String, Parameter> actionParameters)
throws DataProviderException {
- return ActionData.primitiveAction(name, actionParameters);
+ return ActionData.primitiveCollectionAction(name, actionParameters, odata);
}
- public Property processActionPrimitiveCollection(String name, Map<String, Parameter> actionParameters)
+ public EntityActionResult processActionEntity(final String name, final Map<String, Parameter> actionParameters)
throws DataProviderException {
- return ActionData.primitiveCollectionAction(name, actionParameters);
+ return ActionData.entityAction(name, actionParameters, data, odata, edm);
}
- public void setEdm(final Edm edm) {
- this.edm = edm;
+ public EntityCollection processActionEntityCollection(final String name,
+ final Map<String, Parameter> actionParameters) throws DataProviderException {
+ return ActionData.entityCollectionAction(name, actionParameters, odata, edm);
}
- public void setOData(final OData odata) {
- this.odata = odata;
+ public void createReference(final Entity entity, final EdmNavigationProperty navigationProperty, final URI entityId,
+ final String rawServiceRoot) throws DataProviderException {
+ setLink(navigationProperty, entity, getEntityByReference(entityId.toASCIIString(), rawServiceRoot));
}
- public static class DataProviderException extends ODataApplicationException {
- private static final long serialVersionUID = 5098059649321796156L;
+ public void deleteReference(final Entity entity, final EdmNavigationProperty navigationProperty,
+ final String entityId, final String rawServiceRoot) throws DataProviderException {
- public DataProviderException(final String message, final Throwable throwable) {
- super(message, HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT, throwable);
+ if (navigationProperty.isCollection()) {
+ final Entity targetEntity = getEntityByReference(entityId, rawServiceRoot);
+ final Link navigationLink = entity.getNavigationLink(navigationProperty.getName());
+
+ if (navigationLink != null && navigationLink.getInlineEntitySet() != null
+ && navigationLink.getInlineEntitySet().getEntities().contains(targetEntity)) {
+
+ // Remove partner single-valued navigation property
+ if (navigationProperty.getPartner() != null) {
+ final EdmNavigationProperty edmPartnerNavigationProperty = navigationProperty.getPartner();
+ if (!edmPartnerNavigationProperty.isCollection() && !edmPartnerNavigationProperty.isNullable()) {
+ throw new DataProviderException("Navigation property must not be null", HttpStatusCode.BAD_REQUEST);
+ } else if (!edmPartnerNavigationProperty.isCollection()) {
+ removeLink(edmPartnerNavigationProperty, targetEntity);
+ } else if (edmPartnerNavigationProperty.isCollection()
+ && edmPartnerNavigationProperty.getPartner() != null) {
+ // Bidirectional referential constraint
+ final Link partnerNavigationLink = targetEntity.getNavigationLink(edmPartnerNavigationProperty.getName());
+ if (partnerNavigationLink != null && partnerNavigationLink.getInlineEntitySet() != null) {
+ partnerNavigationLink.getInlineEntitySet().getEntities().remove(entity);
+ }
+ }
+ }
+
+ // Remove target entity from collection-valued navigation property
+ navigationLink.getInlineEntitySet().getEntities().remove(targetEntity);
+ } else {
+ throw new DataProviderException("Entity not found", HttpStatusCode.NOT_FOUND);
+ }
+ } else {
+ if (navigationProperty.isNullable()) {
+ removeLink(navigationProperty, entity);
+ } else {
+ throw new DataProviderException("Navigation property must not be null", HttpStatusCode.BAD_REQUEST);
+ }
}
+ }
- public DataProviderException(final String message) {
- super(message, HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT);
+ protected Entity getEntityByReference(final String entityId, final String rawServiceRoot)
+ throws DataProviderException {
+ try {
+ final UriResourceEntitySet uriResource = odata.createUriHelper().parseEntityId(edm, entityId, rawServiceRoot);
+ final Entity targetEntity = read(uriResource.getEntitySet(), uriResource.getKeyPredicates());
+
+ if (targetEntity != null) {
+ return targetEntity;
+ } else {
+ throw new DataProviderException("Entity not found", HttpStatusCode.NOT_FOUND);
+ }
+ } catch (DeserializerException e) {
+ throw new DataProviderException("Invalid entity-id", HttpStatusCode.BAD_REQUEST, e);
}
+ }
- public DataProviderException(final String message, HttpStatusCode statusCode) {
+ public static class DataProviderException extends ODataApplicationException {
+ private static final long serialVersionUID = 5098059649321796156L;
+
+ public DataProviderException(final String message, final HttpStatusCode statusCode) {
super(message, statusCode.getStatusCode(), Locale.ROOT);
}
+
+ public DataProviderException(final String message, final HttpStatusCode statusCode, final Throwable throwable) {
+ super(message, statusCode.getStatusCode(), Locale.ROOT, throwable);
+ }
}
+
++ //CHECKSTYLE:OFF
++ public static void setDefaultTimeZone(String tz) {
++ System.setProperty("defaultTimeZoneForEdmDateTypes", tz);
++ }
++ //CHECKSTYLE:ON
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f63bba70/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/DataProviderTest.java
----------------------------------------------------------------------
diff --cc lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/DataProviderTest.java
index 6bd6463,c9a8e65..b2bf587
--- a/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/DataProviderTest.java
+++ b/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/DataProviderTest.java
@@@ -21,6 -21,6 +21,7 @@@ package org.apache.olingo.server.tecsvc
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
++import java.util.TimeZone;
import org.apache.olingo.commons.api.data.ComplexValue;
import org.apache.olingo.commons.api.data.Entity;
@@@ -33,7 -34,7 +34,9 @@@ import org.apache.olingo.server.api.ODa
import org.apache.olingo.server.api.edmx.EdmxReference;
import org.apache.olingo.server.api.uri.UriParameter;
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
++import org.junit.After;
import org.junit.Assert;
++import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
@@@ -52,9 -53,9 +55,19 @@@ public class DataProviderTest
private final EdmEntitySet esMixPrimCollComp = entityContainer.getEntitySet("ESMixPrimCollComp");
private final EdmEntitySet esMedia = entityContainer.getEntitySet("ESMedia");
++ @Before
++ public void setup() {
++ DataProvider.setDefaultTimeZone("GMT");
++ }
++
++ @After
++ public void teardown() {
++ DataProvider.setDefaultTimeZone(TimeZone.getDefault().getID());
++ }
++
@Test
public void esAllPrimEntity() throws Exception {
- final DataProvider dataProvider = new DataProvider();
+ final DataProvider dataProvider = new DataProvider(oData, edm);
final Entity entity = dataProvider.readAll(esAllPrim).getEntities().get(2);
Assert.assertEquals(16, entity.getProperties().size());
@@@ -82,6 -83,6 +95,7 @@@
mockParameter("PropertySByte", "127"),
mockParameter("PropertyString", "'First'"),
mockParameter("PropertyTimeOfDay", "02:48:21"))));
++
}
@Test
[18/22] olingo-odata4 git commit: OLINGO-861: Adding support to
resolve entities defined in the reference documents
Posted by mi...@apache.org.
OLINGO-861: Adding support to resolve entities defined in the reference documents
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/801899a0
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/801899a0
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/801899a0
Branch: refs/heads/OLINGO-832_StreamSerializerPoC
Commit: 801899a0859bb2aa6bad567d7cff243b0c25a58d
Parents: 7a68ae6
Author: Ramesh Reddy <ra...@jboss.org>
Authored: Wed Feb 10 10:03:20 2016 -0600
Committer: Ramesh Reddy <ra...@jboss.org>
Committed: Wed Feb 10 10:03:20 2016 -0600
----------------------------------------------------------------------
.../olingo/server/core/MetadataParser.java | 66 ++++++++++--
.../olingo/server/core/ReferenceResolver.java | 32 ++++++
.../server/core/SchemaBasedEdmProvider.java | 104 ++++++++++++++++---
3 files changed, 180 insertions(+), 22 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/801899a0/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
index e8122d7..b564792 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
@@ -18,9 +18,12 @@
*/
package org.apache.olingo.server.core;
+import java.io.IOException;
import java.io.Reader;
+import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
+import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
@@ -33,6 +36,7 @@ import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
+import org.apache.olingo.commons.api.edm.EdmException;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.geo.SRID;
import org.apache.olingo.commons.api.edm.provider.CsdlAction;
@@ -42,7 +46,6 @@ import org.apache.olingo.commons.api.edm.provider.CsdlAnnotation;
import org.apache.olingo.commons.api.edm.provider.CsdlAnnotations;
import org.apache.olingo.commons.api.edm.provider.CsdlBindingTarget;
import org.apache.olingo.commons.api.edm.provider.CsdlComplexType;
-import org.apache.olingo.commons.api.edm.provider.CsdlEdmProvider;
import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer;
import org.apache.olingo.commons.api.edm.provider.CsdlEntitySet;
import org.apache.olingo.commons.api.edm.provider.CsdlEntityType;
@@ -92,16 +95,22 @@ import org.apache.olingo.server.api.edmx.EdmxReferenceIncludeAnnotation;
*/
public class MetadataParser {
private boolean parseAnnotations = false;
-
+ private final String XML_LINK_NS = "http://www.w3.org/1999/xlink";
+ private ReferenceResolver referenceResolver = new DefaultReferenceResolver();
+
public void setParseAnnotations(boolean f) {
this.parseAnnotations = true;
}
+ public void setReferenceResolver(ReferenceResolver resolver) {
+ this.referenceResolver = resolver;
+ }
+
public ServiceMetadata buildServiceMetadata(Reader csdl) throws XMLStreamException {
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
XMLEventReader reader = xmlInputFactory.createXMLEventReader(csdl);
- SchemaBasedEdmProvider provider = new SchemaBasedEdmProvider();
+ SchemaBasedEdmProvider provider = new SchemaBasedEdmProvider(referenceResolver);
final ArrayList<EdmxReference> references = new ArrayList<EdmxReference>();
new ElementReader<SchemaBasedEdmProvider>() {
@@ -109,6 +118,8 @@ public class MetadataParser {
void build(XMLEventReader reader, StartElement element, SchemaBasedEdmProvider provider,
String name) throws XMLStreamException {
String version = attr(element, "Version");
+ String xmlBase = attrNS(element, XML_LINK_NS, "base");
+ provider.setXMLBase(xmlBase);
if ("4.0".equals(version)) {
readDataServicesAndReference(reader, element, provider, references);
} else {
@@ -124,14 +135,18 @@ public class MetadataParser {
event.asStartElement().getName().getLocalPart() :
event.asEndElement().getName().getLocalPart()));
}
+ provider.addReferences(references);
return new ServiceMetadataImpl(provider, references, null);
}
- CsdlEdmProvider buildEdmProvider(Reader csdl) throws XMLStreamException {
+ SchemaBasedEdmProvider buildEdmProvider(Reader csdl) throws XMLStreamException {
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
XMLEventReader reader = xmlInputFactory.createXMLEventReader(csdl);
-
- SchemaBasedEdmProvider provider = new SchemaBasedEdmProvider();
+ return buildEdmProvider(reader);
+ }
+
+ SchemaBasedEdmProvider buildEdmProvider(XMLEventReader reader) throws XMLStreamException {
+ SchemaBasedEdmProvider provider = new SchemaBasedEdmProvider(this.referenceResolver);
new ElementReader<SchemaBasedEdmProvider>() {
@Override
void build(XMLEventReader reader, StartElement element, SchemaBasedEdmProvider provider,
@@ -141,8 +156,7 @@ public class MetadataParser {
readDataServicesAndReference(reader, element, provider, new ArrayList<EdmxReference>());
}
}
- }.read(reader, null, provider, "Edmx");
-
+ }.read(reader, null, provider, "Edmx");
return provider;
}
@@ -776,6 +790,14 @@ public class MetadataParser {
return null;
}
+ private String attrNS(StartElement element, String ns, String name) {
+ Attribute attr = element.getAttributeByName(new QName(ns, name));
+ if (attr != null) {
+ return attr.getValue();
+ }
+ return null;
+ }
+
private CsdlProperty readProperty(XMLEventReader reader, StartElement element)
throws XMLStreamException {
CsdlProperty property = new CsdlProperty();
@@ -1020,4 +1042,32 @@ public class MetadataParser {
abstract void build(XMLEventReader reader, StartElement element, T t, String name)
throws XMLStreamException;
}
+
+ class DefaultReferenceResolver implements ReferenceResolver{
+ @Override
+ public SchemaBasedEdmProvider resolveReference(URI referenceUri, String xmlBase) {
+ URL schemaURL = null;
+ try {
+ if (referenceUri.isAbsolute()) {
+ schemaURL = referenceUri.toURL();
+ } else {
+ if (xmlBase != null) {
+ schemaURL = new URL(xmlBase+referenceUri.toString());
+ } else {
+ throw new EdmException("No xml:base set to read the references from the metadata");
+ }
+ }
+
+ XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
+ XMLEventReader reader = xmlInputFactory.createXMLEventReader(schemaURL.openStream());
+ return buildEdmProvider(reader);
+ } catch (MalformedURLException e) {
+ throw new EdmException(e);
+ } catch (XMLStreamException e) {
+ throw new EdmException(e);
+ } catch (IOException e) {
+ throw new EdmException(e);
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/801899a0/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ReferenceResolver.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ReferenceResolver.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ReferenceResolver.java
new file mode 100644
index 0000000..f7d5101
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ReferenceResolver.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.server.core;
+
+import java.net.URI;
+
+public interface ReferenceResolver {
+ /**
+ * Resolve the reference locally or from redirection from different source than defined in the
+ * metadata document.
+ * @param referenceUri reference URI for the schema file
+ * @param xmlBase xml:base if provided by the metadata document; null otherwise
+ * @return
+ */
+ SchemaBasedEdmProvider resolveReference(URI referenceUri, String xmlBase);
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/801899a0/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/SchemaBasedEdmProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/SchemaBasedEdmProvider.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/SchemaBasedEdmProvider.java
index 0612302..a2f23f6 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/SchemaBasedEdmProvider.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/SchemaBasedEdmProvider.java
@@ -19,8 +19,9 @@
package org.apache.olingo.server.core;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.provider.CsdlAction;
@@ -41,11 +42,22 @@ import org.apache.olingo.commons.api.edm.provider.CsdlSingleton;
import org.apache.olingo.commons.api.edm.provider.CsdlTerm;
import org.apache.olingo.commons.api.edm.provider.CsdlTypeDefinition;
import org.apache.olingo.commons.api.ex.ODataException;
+import org.apache.olingo.server.api.edmx.EdmxReference;
+import org.apache.olingo.server.api.edmx.EdmxReferenceInclude;
public class SchemaBasedEdmProvider implements CsdlEdmProvider {
private final List<CsdlSchema> edmSchemas = new ArrayList<CsdlSchema>();
+ private final Map<String, EdmxReference> references = new ConcurrentHashMap<String, EdmxReference>();
+ private final Map<String, SchemaBasedEdmProvider> referenceSchemas
+ = new ConcurrentHashMap<String, SchemaBasedEdmProvider>();
+ private String xmlBase;
+ private ReferenceResolver referenceResolver;
+
+ public SchemaBasedEdmProvider(ReferenceResolver referenceResolver) {
+ this.referenceResolver = referenceResolver;
+ }
- public void addSchema(CsdlSchema schema) {
+ void addSchema(CsdlSchema schema) {
this.edmSchemas.add(schema);
}
@@ -55,6 +67,39 @@ public class SchemaBasedEdmProvider implements CsdlEdmProvider {
return s;
}
}
+ return getReferenceSchema(ns);
+ }
+
+ private CsdlSchema getReferenceSchema(String ns) {
+ if (ns == null) {
+ return null;
+ }
+ if (this.referenceSchemas.get(ns) == null) {
+ EdmxReference reference = this.references.get(ns);
+ if (reference != null) {
+ SchemaBasedEdmProvider provider = this.referenceResolver.resolveReference(reference.getUri(), xmlBase);
+ for (EdmxReferenceInclude include : reference.getIncludes()) {
+ this.referenceSchemas.put(include.getNamespace(), provider);
+ if (include.getAlias() != null) {
+ CsdlSchema schema = provider.getSchema(include.getNamespace());
+ schema.setAlias(include.getAlias());
+ this.referenceSchemas.put(include.getAlias(), provider);
+ }
+ }
+ }
+ }
+
+ if (this.referenceSchemas.get(ns) != null) {
+ return this.referenceSchemas.get(ns).getSchema(ns);
+ }
+
+ // it is possible that we may be looking for Reference schema of Reference
+ for (SchemaBasedEdmProvider provider:this.referenceSchemas.values()) {
+ CsdlSchema schema = provider.getSchema(ns);
+ if (schema != null) {
+ return schema;
+ }
+ }
return null;
}
@@ -220,22 +265,26 @@ public class SchemaBasedEdmProvider implements CsdlEdmProvider {
@Override
public List<CsdlAliasInfo> getAliasInfos() throws ODataException {
- CsdlSchema schema = null;
+ ArrayList<CsdlAliasInfo> list = new ArrayList<CsdlAliasInfo>();
for (CsdlSchema s : this.edmSchemas) {
- if (s.getEntityContainer() != null) {
- schema = s;
- break;
+ if (s.getAlias() != null) {
+ CsdlAliasInfo ai = new CsdlAliasInfo();
+ ai.setAlias(s.getAlias());
+ ai.setNamespace(s.getNamespace());
+ list.add(ai);
}
}
-
- if (schema == null) {
- schema = this.edmSchemas.get(0);
+ for(EdmxReference reference:this.references.values()) {
+ for(EdmxReferenceInclude include:reference.getIncludes()) {
+ if (include.getAlias() != null) {
+ CsdlAliasInfo ai = new CsdlAliasInfo();
+ ai.setAlias(include.getAlias());
+ ai.setNamespace(include.getNamespace());
+ list.add(ai);
+ }
+ }
}
-
- CsdlAliasInfo ai = new CsdlAliasInfo();
- ai.setAlias(schema.getAlias());
- ai.setNamespace(schema.getNamespace());
- return Arrays.asList(ai);
+ return list;
}
@Override
@@ -304,6 +353,33 @@ public class SchemaBasedEdmProvider implements CsdlEdmProvider {
@Override
public CsdlAnnotations getAnnotationsGroup(FullQualifiedName targetName, String qualifier) throws ODataException {
+ CsdlSchema schema = getSchema(targetName.getNamespace());
+ if (schema != null) {
+ return schema.getAnnotationGroup(targetName.getName(), qualifier);
+ }
return null;
}
+
+ void addReferences(ArrayList<EdmxReference> references) {
+ if (references != null && !references.isEmpty()) {
+ for (EdmxReference ref:references) {
+ for (EdmxReferenceInclude include : ref.getIncludes()) {
+ if (include.getAlias() != null) {
+ this.references.put(include.getAlias(), ref);
+ }
+ this.references.put(include.getNamespace(), ref);
+ }
+ }
+ }
+ }
+
+ public void setXMLBase(String base) {
+ if (base != null) {
+ if (base.endsWith("/")) {
+ this.xmlBase = base;
+ } else {
+ this.xmlBase = base+"/";
+ }
+ }
+ }
}
[04/22] olingo-odata4 git commit: [OLINGO-834] better alias support
in URI parser
Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/expression/AliasImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/expression/AliasImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/expression/AliasImpl.java
index f506dc2..07602c2 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/expression/AliasImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/expression/AliasImpl.java
@@ -19,6 +19,7 @@
package org.apache.olingo.server.core.uri.queryoption.expression;
import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.uri.queryoption.AliasQueryOption;
import org.apache.olingo.server.api.uri.queryoption.expression.Alias;
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitException;
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitor;
@@ -26,9 +27,11 @@ import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitor
public class AliasImpl implements Alias {
private final String parameterName;
+ private final AliasQueryOption alias;
- public AliasImpl(final String parameterName) {
+ public AliasImpl(final String parameterName, final AliasQueryOption alias) {
this.parameterName = parameterName;
+ this.alias = alias;
}
@Override
@@ -36,6 +39,10 @@ public class AliasImpl implements Alias {
return parameterName;
}
+ public AliasQueryOption getAlias() {
+ return alias;
+ }
+
@Override
public <T> T accept(final ExpressionVisitor<T> visitor) throws ExpressionVisitException, ODataApplicationException {
return visitor.visitAlias(parameterName);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidationException.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidationException.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidationException.java
index 1656150..2b446a7 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidationException.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidationException.java
@@ -56,7 +56,9 @@ public class UriValidationException extends ODataLibraryException {
/** parameter: unallowed resource path */
UNALLOWED_RESOURCE_PATH,
/** parameter: missing parameter name */
- MISSING_PARAMETER;
+ MISSING_PARAMETER,
+ /** parameter: missing alias name */
+ MISSING_ALIAS;
@Override
public String getKey() {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidator.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidator.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidator.java
index 5d842fb..cec2fc0 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidator.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidator.java
@@ -18,28 +18,22 @@
*/
package org.apache.olingo.server.core.uri.validator;
-import java.util.HashMap;
+import java.util.Collections;
+import java.util.EnumMap;
import java.util.List;
import java.util.Map;
-import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmFunction;
-import org.apache.olingo.commons.api.edm.EdmKeyPropertyRef;
-import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
-import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.edm.EdmReturnType;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.server.api.uri.UriInfo;
-import org.apache.olingo.server.api.uri.UriParameter;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourceAction;
-import org.apache.olingo.server.api.uri.UriResourceEntitySet;
import org.apache.olingo.server.api.uri.UriResourceFunction;
import org.apache.olingo.server.api.uri.UriResourceKind;
-import org.apache.olingo.server.api.uri.UriResourceNavigation;
import org.apache.olingo.server.api.uri.UriResourcePartTyped;
import org.apache.olingo.server.api.uri.UriResourceProperty;
import org.apache.olingo.server.api.uri.queryoption.SystemQueryOption;
@@ -49,7 +43,7 @@ public class UriValidator {
//@formatter:off (Eclipse formatter)
//CHECKSTYLE:OFF (Maven checkstyle)
- private final boolean[][] decisionMatrix =
+ private static final boolean[][] decisionMatrix =
{
/* 0-FILTER 1-FORMAT 2-EXPAND 3-ID 4-COUNT 5-ORDERBY 6-SEARCH 7-SELECT 8-SKIP 9-SKIPTOKEN 10-TOP */
/* all 0 */ { true , true , true , false, true , true , true , true , true , true , true },
@@ -62,7 +56,7 @@ public class UriValidator {
/* entitySetCount 7 */ { true , false, false, false, false, false, true , false, false, false, false },
/* entity 8 */ { false, true , true , false, false, false, false, true , false, false, false },
/* mediaStream 9 */ { false, false, false, false, false, false, false, false, false, false, false },
- /* references 10 */ { true , true , false, true , true , true , true , false, true , true , true },
+ /* references 10 */ { true , true , false, false, true , true , true , false, true , true , true },
/* reference 11 */ { false, true , false, false, false, false, false, false, false, false, false },
/* propertyComplex 12 */ { false, true , true , false, false, false, false, true , false, false, false },
/* propertyComplexCollection 13 */ { true , true , true , false, true , true , false, true , true , true , true },
@@ -76,7 +70,7 @@ public class UriValidator {
//CHECKSTYLE:ON
//@formatter:on
- private enum RowIndexForUriType {
+ private enum UriType {
all(0),
batch(1),
crossjoin(2),
@@ -100,7 +94,7 @@ public class UriValidator {
private final int idx;
- RowIndexForUriType(final int i) {
+ UriType(final int i) {
idx = i;
}
@@ -109,308 +103,230 @@ public class UriValidator {
}
}
- private enum ColumnIndex {
- filter(0),
- format(1),
- expand(2),
- id(3),
- count(4),
- orderby(5),
- search(6),
- select(7),
- skip(8),
- skiptoken(9),
- top(10);
-
- private final int idx;
-
- ColumnIndex(final int i) {
- idx = i;
- }
-
- public int getIndex() {
- return idx;
- }
+ private static Map<SystemQueryOptionKind, Integer> OPTION_INDEX;
+ static {
+ Map<SystemQueryOptionKind, Integer> temp =
+ new EnumMap<SystemQueryOptionKind, Integer>(SystemQueryOptionKind.class);
+ temp.put(SystemQueryOptionKind.FILTER, 0);
+ temp.put(SystemQueryOptionKind.FORMAT, 1);
+ temp.put(SystemQueryOptionKind.EXPAND, 2);
+ temp.put(SystemQueryOptionKind.ID, 3);
+ temp.put(SystemQueryOptionKind.COUNT, 4);
+ temp.put(SystemQueryOptionKind.ORDERBY, 5);
+ temp.put(SystemQueryOptionKind.SEARCH, 6);
+ temp.put(SystemQueryOptionKind.SELECT, 7);
+ temp.put(SystemQueryOptionKind.SKIP, 8);
+ temp.put(SystemQueryOptionKind.SKIPTOKEN, 9);
+ temp.put(SystemQueryOptionKind.TOP, 10);
+ OPTION_INDEX = Collections.unmodifiableMap(temp);
}
public void validate(final UriInfo uriInfo, final HttpMethod httpMethod) throws UriValidationException {
- if (HttpMethod.GET != httpMethod) {
- validateForHttpMethod(uriInfo, httpMethod);
- }
- validateQueryOptions(uriInfo);
- validateParameters(uriInfo);
- validateKeyPredicates(uriInfo);
- validatePropertyOperations(uriInfo, httpMethod);
- }
-
- private ColumnIndex colIndex(final SystemQueryOptionKind queryOptionKind) throws UriValidationException {
- ColumnIndex idx;
- switch (queryOptionKind) {
- case FILTER:
- idx = ColumnIndex.filter;
- break;
- case FORMAT:
- idx = ColumnIndex.format;
- break;
- case EXPAND:
- idx = ColumnIndex.expand;
- break;
- case ID:
- idx = ColumnIndex.id;
- break;
- case COUNT:
- idx = ColumnIndex.count;
- break;
- case ORDERBY:
- idx = ColumnIndex.orderby;
- break;
- case SEARCH:
- idx = ColumnIndex.search;
- break;
- case SELECT:
- idx = ColumnIndex.select;
- break;
- case SKIP:
- idx = ColumnIndex.skip;
- break;
- case SKIPTOKEN:
- idx = ColumnIndex.skiptoken;
- break;
- case TOP:
- idx = ColumnIndex.top;
- break;
- default:
- throw new UriValidationException("Unsupported option: " + queryOptionKind.toString(),
- UriValidationException.MessageKeys.UNSUPPORTED_QUERY_OPTION, queryOptionKind.toString());
+ final UriType uriType = getUriType(uriInfo);
+ if (HttpMethod.GET == httpMethod) {
+ validateReadQueryOptions(uriType, uriInfo.getSystemQueryOptions());
+ } else {
+ validateNonReadQueryOptions(uriType, isAction(uriInfo), uriInfo.getSystemQueryOptions(), httpMethod);
+ validatePropertyOperations(uriInfo, httpMethod);
}
-
- return idx;
}
- private RowIndexForUriType rowIndexForUriType(final UriInfo uriInfo) throws UriValidationException {
- RowIndexForUriType idx;
+ private UriType getUriType(final UriInfo uriInfo) throws UriValidationException {
+ UriType uriType;
switch (uriInfo.getKind()) {
case all:
- idx = RowIndexForUriType.all;
+ uriType = UriType.all;
break;
case batch:
- idx = RowIndexForUriType.batch;
+ uriType = UriType.batch;
break;
case crossjoin:
- idx = RowIndexForUriType.crossjoin;
+ uriType = UriType.crossjoin;
break;
case entityId:
- idx = RowIndexForUriType.entityId;
+ uriType = UriType.entityId;
break;
case metadata:
- idx = RowIndexForUriType.metadata;
+ uriType = UriType.metadata;
break;
case resource:
- idx = rowIndexForResourceKind(uriInfo);
+ uriType = getUriTypeForResource(uriInfo.getUriResourceParts());
break;
case service:
- idx = RowIndexForUriType.service;
+ uriType = UriType.service;
break;
default:
throw new UriValidationException("Unsupported uriInfo kind: " + uriInfo.getKind(),
UriValidationException.MessageKeys.UNSUPPORTED_URI_KIND, uriInfo.getKind().toString());
}
- return idx;
+ return uriType;
}
- private RowIndexForUriType rowIndexForResourceKind(final UriInfo uriInfo) throws UriValidationException {
- RowIndexForUriType idx;
- int lastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 1;
- UriResource lastPathSegment = uriInfo.getUriResourceParts().get(lastPathSegmentIndex);
+ /**
+ * Determines the URI type for a resource path.
+ * The URI parser has already made sure that there are enough segments for a given type of the last segment,
+ * but don't try to extract always the second-to-last segment, it could cause an {@link IndexOutOfBoundsException}.
+ */
+ private UriType getUriTypeForResource(final List<UriResource> segments) throws UriValidationException {
+ final UriResource lastPathSegment = segments.get(segments.size() - 1);
+ UriType uriType;
switch (lastPathSegment.getKind()) {
case count:
- idx = rowIndexForCount(uriInfo);
+ uriType = getUriTypeForCount(segments.get(segments.size() - 2));
break;
case action:
- idx = rowIndexForAction(lastPathSegment);
+ uriType = getUriTypeForAction(lastPathSegment);
break;
case complexProperty:
- idx = rowIndexForComplexProperty(lastPathSegment);
+ uriType = getUriTypeForComplexProperty(lastPathSegment);
break;
case entitySet:
case navigationProperty:
- idx = rowIndexForEntitySet(lastPathSegment);
+ uriType = getUriTypeForEntitySet(lastPathSegment);
break;
case function:
- idx = rowIndexForFunction(lastPathSegment);
+ uriType = getUriTypeForFunction(lastPathSegment);
break;
case primitiveProperty:
- idx = rowIndexForPrimitiveProperty(lastPathSegment);
+ uriType = getUriTypeForPrimitiveProperty(lastPathSegment);
break;
case ref:
- idx = rowIndexForRef(uriInfo, lastPathSegment);
- break;
- case root:
- idx = RowIndexForUriType.service;
+ uriType = getUriTypeForRef(segments.get(segments.size() - 2));
break;
case singleton:
- idx = RowIndexForUriType.entity;
+ uriType = UriType.entity;
break;
case value:
- idx = rowIndexForValue(uriInfo);
+ uriType = getUriTypeForValue(segments.get(segments.size() - 2));
break;
default:
throw new UriValidationException("Unsupported uriResource kind: " + lastPathSegment.getKind(),
UriValidationException.MessageKeys.UNSUPPORTED_URI_RESOURCE_KIND, lastPathSegment.getKind().toString());
}
- return idx;
+ return uriType;
}
- private RowIndexForUriType rowIndexForValue(final UriInfo uriInfo) throws UriValidationException {
- RowIndexForUriType idx;
- int secondLastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 2;
- UriResource secondLastPathSegment = uriInfo.getUriResourceParts().get(secondLastPathSegmentIndex);
-
+ private UriType getUriTypeForValue(final UriResource secondLastPathSegment) throws UriValidationException {
+ UriType uriType;
switch (secondLastPathSegment.getKind()) {
case primitiveProperty:
- idx = RowIndexForUriType.propertyPrimitiveValue;
+ uriType = UriType.propertyPrimitiveValue;
break;
case entitySet:
case navigationProperty:
case singleton:
- idx = RowIndexForUriType.mediaStream;
+ uriType = UriType.mediaStream;
break;
case function:
UriResourceFunction uriFunction = (UriResourceFunction) secondLastPathSegment;
final EdmFunction function = uriFunction.getFunction();
- idx = function.getReturnType().getType().getKind() == EdmTypeKind.ENTITY ?
- RowIndexForUriType.mediaStream : RowIndexForUriType.propertyPrimitiveValue;
+ uriType = function.getReturnType().getType().getKind() == EdmTypeKind.ENTITY ?
+ UriType.mediaStream : UriType.propertyPrimitiveValue;
break;
default:
throw new UriValidationException(
"Unexpected kind in path segment before $value: " + secondLastPathSegment.getKind(),
UriValidationException.MessageKeys.UNALLOWED_KIND_BEFORE_VALUE, secondLastPathSegment.toString());
}
- return idx;
+ return uriType;
}
- private RowIndexForUriType rowIndexForRef(final UriInfo uriInfo, final UriResource lastPathSegment)
- throws UriValidationException {
- int secondLastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 2;
- UriResource secondLastPathSegment = uriInfo.getUriResourceParts().get(secondLastPathSegmentIndex);
+ private UriType getUriTypeForRef(final UriResource secondLastPathSegment) throws UriValidationException {
+ return isCollection(secondLastPathSegment) ? UriType.references : UriType.reference;
+ }
- if (secondLastPathSegment instanceof UriResourcePartTyped) {
- return ((UriResourcePartTyped) secondLastPathSegment).isCollection() ?
- RowIndexForUriType.references : RowIndexForUriType.reference;
+ private boolean isCollection(final UriResource pathSegment) throws UriValidationException {
+ if (pathSegment instanceof UriResourcePartTyped) {
+ return ((UriResourcePartTyped) pathSegment).isCollection();
} else {
throw new UriValidationException(
- "secondLastPathSegment not a class of UriResourcePartTyped: " + lastPathSegment.getClass(),
- UriValidationException.MessageKeys.LAST_SEGMENT_NOT_TYPED, lastPathSegment.toString());
+ "Path segment is not an instance of UriResourcePartTyped but " + pathSegment.getClass(),
+ UriValidationException.MessageKeys.LAST_SEGMENT_NOT_TYPED, pathSegment.toString());
}
}
- private RowIndexForUriType rowIndexForPrimitiveProperty(final UriResource lastPathSegment)
- throws UriValidationException {
- if (lastPathSegment instanceof UriResourcePartTyped) {
- return ((UriResourcePartTyped) lastPathSegment).isCollection() ?
- RowIndexForUriType.propertyPrimitiveCollection : RowIndexForUriType.propertyPrimitive;
- } else {
- throw new UriValidationException(
- "lastPathSegment not a class of UriResourcePartTyped: " + lastPathSegment.getClass(),
- UriValidationException.MessageKeys.LAST_SEGMENT_NOT_TYPED, lastPathSegment.toString());
- }
+ private UriType getUriTypeForPrimitiveProperty(final UriResource lastPathSegment) throws UriValidationException {
+ return isCollection(lastPathSegment) ? UriType.propertyPrimitiveCollection : UriType.propertyPrimitive;
}
- private RowIndexForUriType rowIndexForFunction(final UriResource lastPathSegment) throws UriValidationException {
+ private UriType getUriTypeForFunction(final UriResource lastPathSegment) throws UriValidationException {
final UriResourceFunction uriFunction = (UriResourceFunction) lastPathSegment;
if (!uriFunction.getFunction().isComposable()) {
- return RowIndexForUriType.none;
+ return UriType.none;
}
final boolean isCollection = uriFunction.isCollection();
final EdmTypeKind typeKind = uriFunction.getFunction().getReturnType().getType().getKind();
- RowIndexForUriType idx;
+ UriType uriType;
switch (typeKind) {
case ENTITY:
- idx = isCollection ? RowIndexForUriType.entitySet : RowIndexForUriType.entity;
+ uriType = isCollection ? UriType.entitySet : UriType.entity;
break;
case PRIMITIVE:
case ENUM:
case DEFINITION:
- idx = isCollection ? RowIndexForUriType.propertyPrimitiveCollection : RowIndexForUriType.propertyPrimitive;
+ uriType = isCollection ? UriType.propertyPrimitiveCollection : UriType.propertyPrimitive;
break;
case COMPLEX:
- idx = isCollection ? RowIndexForUriType.propertyComplexCollection : RowIndexForUriType.propertyComplex;
+ uriType = isCollection ? UriType.propertyComplexCollection : UriType.propertyComplex;
break;
default:
throw new UriValidationException("Unsupported function return type: " + typeKind,
UriValidationException.MessageKeys.UNSUPPORTED_FUNCTION_RETURN_TYPE, typeKind.toString());
}
- return idx;
+ return uriType;
}
- private RowIndexForUriType rowIndexForEntitySet(final UriResource lastPathSegment) throws UriValidationException {
- if (lastPathSegment instanceof UriResourcePartTyped) {
- return ((UriResourcePartTyped) lastPathSegment).isCollection() ?
- RowIndexForUriType.entitySet : RowIndexForUriType.entity;
- } else {
- throw new UriValidationException("lastPathSegment not a class of UriResourcePartTyped: "
- + lastPathSegment.getClass(), UriValidationException.MessageKeys.LAST_SEGMENT_NOT_TYPED,
- lastPathSegment.toString());
- }
+ private UriType getUriTypeForEntitySet(final UriResource lastPathSegment) throws UriValidationException {
+ return isCollection(lastPathSegment) ? UriType.entitySet : UriType.entity;
}
- private RowIndexForUriType rowIndexForComplexProperty(final UriResource lastPathSegment)
- throws UriValidationException {
- if (lastPathSegment instanceof UriResourcePartTyped) {
- return ((UriResourcePartTyped) lastPathSegment).isCollection() ?
- RowIndexForUriType.propertyComplexCollection : RowIndexForUriType.propertyComplex;
- } else {
- throw new UriValidationException("lastPathSegment not a class of UriResourcePartTyped: "
- + lastPathSegment.getClass(), UriValidationException.MessageKeys.LAST_SEGMENT_NOT_TYPED,
- lastPathSegment.toString());
- }
+ private UriType getUriTypeForComplexProperty(final UriResource lastPathSegment) throws UriValidationException {
+ return isCollection(lastPathSegment) ? UriType.propertyComplexCollection : UriType.propertyComplex;
}
- private RowIndexForUriType rowIndexForAction(final UriResource lastPathSegment) throws UriValidationException {
+ private UriType getUriTypeForAction(final UriResource lastPathSegment) throws UriValidationException {
final EdmReturnType rt = ((UriResourceAction) lastPathSegment).getAction().getReturnType();
if (rt == null) {
- return RowIndexForUriType.none;
+ return UriType.none;
}
- RowIndexForUriType idx;
+ UriType uriType;
switch (rt.getType().getKind()) {
case ENTITY:
- idx = rt.isCollection() ? RowIndexForUriType.entitySet : RowIndexForUriType.entity;
+ uriType = rt.isCollection() ? UriType.entitySet : UriType.entity;
break;
case PRIMITIVE:
case ENUM:
case DEFINITION:
- idx = rt.isCollection() ? RowIndexForUriType.propertyPrimitiveCollection : RowIndexForUriType.propertyPrimitive;
+ uriType = rt.isCollection() ? UriType.propertyPrimitiveCollection : UriType.propertyPrimitive;
break;
case COMPLEX:
- idx = rt.isCollection() ? RowIndexForUriType.propertyComplexCollection : RowIndexForUriType.propertyComplex;
+ uriType = rt.isCollection() ? UriType.propertyComplexCollection : UriType.propertyComplex;
break;
default:
throw new UriValidationException("Unsupported action return type: " + rt.getType().getKind(),
UriValidationException.MessageKeys.UNSUPPORTED_ACTION_RETURN_TYPE, rt.getType().getKind().toString());
}
- return idx;
+ return uriType;
}
- private RowIndexForUriType rowIndexForCount(final UriInfo uriInfo) throws UriValidationException {
- RowIndexForUriType idx;
- int secondLastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 2;
- UriResource secondLastPathSegment = uriInfo.getUriResourceParts().get(secondLastPathSegmentIndex);
+ private UriType getUriTypeForCount(final UriResource secondLastPathSegment) throws UriValidationException {
+ UriType uriType;
switch (secondLastPathSegment.getKind()) {
case entitySet:
case navigationProperty:
- idx = RowIndexForUriType.entitySetCount;
+ uriType = UriType.entitySetCount;
break;
case complexProperty:
- idx = RowIndexForUriType.propertyComplexCollectionCount;
+ uriType = UriType.propertyComplexCollectionCount;
break;
case primitiveProperty:
- idx = RowIndexForUriType.propertyPrimitiveCollectionCount;
+ uriType = UriType.propertyPrimitiveCollectionCount;
break;
case function:
final UriResourceFunction uriFunction = (UriResourceFunction) secondLastPathSegment;
@@ -418,15 +334,15 @@ public class UriValidator {
final EdmType returnType = function.getReturnType().getType();
switch (returnType.getKind()) {
case ENTITY:
- idx = RowIndexForUriType.entitySetCount;
+ uriType = UriType.entitySetCount;
break;
case COMPLEX:
- idx = RowIndexForUriType.propertyComplexCollectionCount;
+ uriType = UriType.propertyComplexCollectionCount;
break;
case PRIMITIVE:
case ENUM:
case DEFINITION:
- idx = RowIndexForUriType.propertyPrimitiveCollectionCount;
+ uriType = UriType.propertyPrimitiveCollectionCount;
break;
default:
throw new UriValidationException("Unsupported return type: " + returnType.getKind(),
@@ -438,80 +354,54 @@ public class UriValidator {
UriValidationException.MessageKeys.UNALLOWED_KIND_BEFORE_COUNT, secondLastPathSegment.toString());
}
- return idx;
+ return uriType;
}
- private void validateQueryOptions(final UriInfo uriInfo) throws UriValidationException {
- RowIndexForUriType row = rowIndexForUriType(uriInfo);
-
- for (SystemQueryOption option : uriInfo.getSystemQueryOptions()) {
- ColumnIndex col = colIndex(option.getKind());
-
- if (!decisionMatrix[row.getIndex()][col.getIndex()]) {
- throw new UriValidationException("System query option not allowed: " + option.getName(),
- UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED, option.getName());
- }
- }
- }
-
- private void validateForHttpMethod(final UriInfo uriInfo, final HttpMethod httpMethod) throws UriValidationException {
- switch (httpMethod) {
- case POST:
- if (!isAction(uriInfo)) {
- // POST and SystemQueryOptions only allowed if addressed resource is an action
- validateNoQueryOptionsForHttpMethod(uriInfo, httpMethod);
- }
- break;
- case DELETE:
- if (!isReferences(uriInfo)) {
- // DELETE and SystemQueryOptions only allowed if addressed resource is a reference collection
- validateNoQueryOptionsForHttpMethod(uriInfo, httpMethod);
- } else {
- // Only $id allowed as SystemQueryOption for DELETE and references
- for (SystemQueryOption option : uriInfo.getSystemQueryOptions()) {
- if (SystemQueryOptionKind.ID != option.getKind()) {
- throw new UriValidationException(
- "System query option " + option.getName() + " not allowed for method " + httpMethod,
- UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED_FOR_HTTP_METHOD,
- option.getName(), httpMethod.toString());
- }
+ private void validateReadQueryOptions(final UriType uriType, final List<SystemQueryOption> options)
+ throws UriValidationException {
+ for (final SystemQueryOption option : options) {
+ final SystemQueryOptionKind kind = option.getKind();
+ if (OPTION_INDEX.containsKey(kind)) {
+ final int columnIndex = OPTION_INDEX.get(kind);
+ if (!decisionMatrix[uriType.getIndex()][columnIndex]) {
+ throw new UriValidationException("System query option not allowed: " + option.getName(),
+ UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED, option.getName());
}
+ } else {
+ throw new UriValidationException("Unsupported option: " + kind,
+ UriValidationException.MessageKeys.UNSUPPORTED_QUERY_OPTION, kind.toString());
}
- break;
- case PUT:
- case PATCH:
- // PUT and PATCH do not allow system query options
- validateNoQueryOptionsForHttpMethod(uriInfo, httpMethod);
- break;
- default:
- throw new UriValidationException("HTTP method not supported: " + httpMethod,
- UriValidationException.MessageKeys.UNSUPPORTED_HTTP_METHOD, httpMethod.toString());
}
-
}
- private boolean isReferences(final UriInfo uriInfo) {
- if (!uriInfo.getSystemQueryOptions().isEmpty()) {
- List<UriResource> uriResourceParts = uriInfo.getUriResourceParts();
- if (UriResourceKind.ref == uriResourceParts.get(uriResourceParts.size() - 1).getKind()) {
- UriResourcePartTyped previousSegment = (UriResourcePartTyped) uriResourceParts.get(uriResourceParts.size() - 2);
- return previousSegment.isCollection();
+ private void validateNonReadQueryOptions(final UriType uriType, final boolean isAction,
+ final List<SystemQueryOption> options, final HttpMethod httpMethod) throws UriValidationException {
+ if (httpMethod == HttpMethod.POST && isAction) {
+ // From the OData specification:
+ // For POST requests to an action URL the return type of the action determines the applicable
+ // system query options that a service MAY support, following the same rules as GET requests.
+ validateReadQueryOptions(uriType, options);
+
+ } else if (httpMethod == HttpMethod.DELETE && uriType == UriType.references) {
+ // Only $id is allowed as SystemQueryOption for DELETE on a reference collection.
+ for (final SystemQueryOption option : options) {
+ if (SystemQueryOptionKind.ID != option.getKind()) {
+ throw new UriValidationException(
+ "System query option " + option.getName() + " is not allowed for method " + httpMethod,
+ UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED_FOR_HTTP_METHOD,
+ option.getName(), httpMethod.toString());
+ }
}
- }
- return false;
- }
- private void validateNoQueryOptionsForHttpMethod(final UriInfo uriInfo, final HttpMethod httpMethod)
- throws UriValidationException {
- if (!uriInfo.getSystemQueryOptions().isEmpty()) {
- StringBuilder options = new StringBuilder();
- for (SystemQueryOption option : uriInfo.getSystemQueryOptions()) {
- options.append(option.getName()).append(" ");
+ } else if (!options.isEmpty()) {
+ StringBuilder optionsString = new StringBuilder();
+ for (final SystemQueryOption option : options) {
+ optionsString.append(option.getName()).append(' ');
}
throw new UriValidationException(
- "System query option " + options.toString() + " not allowed for method " + httpMethod,
+ "System query option(s) " + optionsString.toString() + "not allowed for method " + httpMethod,
UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED_FOR_HTTP_METHOD,
- options.toString(), httpMethod.toString());
+ optionsString.toString(), httpMethod.toString());
}
}
@@ -521,139 +411,6 @@ public class UriValidator {
&& UriResourceKind.action == uriResourceParts.get(uriResourceParts.size() - 1).getKind();
}
- private void validateParameters(final UriInfo uriInfo) throws UriValidationException {
- for (UriResource pathSegment : uriInfo.getUriResourceParts()) {
- final boolean isFunction = pathSegment.getKind() == UriResourceKind.function;
-
- if (isFunction) {
- final UriResourceFunction functionPathSegment = (UriResourceFunction) pathSegment;
- final EdmFunction edmFunction = functionPathSegment.getFunction();
-
- final Map<String, UriParameter> parameters = new HashMap<String, UriParameter>();
- for (final UriParameter parameter : functionPathSegment.getParameters()) {
- parameters.put(parameter.getName(), parameter);
- }
-
- boolean firstParameter = true;
- for (final String parameterName : edmFunction.getParameterNames()) {
- final UriParameter parameter = parameters.get(parameterName);
- final boolean isNullable = edmFunction.getParameter(parameterName).isNullable();
-
- if (parameter != null) {
- /** No alias, value explicit null */
- if (parameter.getText() == null
- && parameter.getAlias() == null && !isNullable) {
- throw new UriValidationException("Missing non nullable parameter " + parameterName,
- UriValidationException.MessageKeys.MISSING_PARAMETER, parameterName);
- } else if (parameter.getText() == null && parameter.getAlias() != null) {
- final String valueForAlias = uriInfo.getValueForAlias(parameter.getAlias());
- /** Alias value is missing or explicit null **/
- if (valueForAlias == null && !isNullable) {
- throw new UriValidationException("Missing non nullable parameter " + parameterName,
- UriValidationException.MessageKeys.MISSING_PARAMETER, parameterName);
- }
- }
-
- parameters.remove(parameterName);
- } else if (!isNullable && !(firstParameter && edmFunction.isBound())) {
- // The first parameter of bound functions is implicit provided by the preceding path segment
- throw new UriValidationException("Missing non nullable parameter " + parameterName,
- UriValidationException.MessageKeys.MISSING_PARAMETER, parameterName);
- }
-
- firstParameter = false;
- }
-
- if (!parameters.isEmpty()) {
- final String parameterName = parameters.keySet().iterator().next();
- throw new UriValidationException("Unsupported parameter " + parameterName,
- UriValidationException.MessageKeys.UNSUPPORTED_PARAMETER, parameterName);
- }
- }
- }
- }
-
- private void validateKeyPredicates(final UriInfo uriInfo) throws UriValidationException {
- for (UriResource pathSegment : uriInfo.getUriResourceParts()) {
- final boolean isEntitySet = pathSegment.getKind() == UriResourceKind.entitySet;
- final boolean isEntityColFunction = isEntityColFunction(pathSegment);
-
- if (isEntitySet || pathSegment.getKind() == UriResourceKind.navigationProperty || isEntityColFunction) {
- final List<UriParameter> keyPredicates = isEntitySet ?
- ((UriResourceEntitySet) pathSegment).getKeyPredicates() :
- isEntityColFunction ?
- ((UriResourceFunction) pathSegment).getKeyPredicates() :
- ((UriResourceNavigation) pathSegment).getKeyPredicates();
-
- if (keyPredicates != null) {
- final EdmEntityType entityType = isEntitySet ?
- ((UriResourceEntitySet) pathSegment).getEntityType() :
- isEntityColFunction ? (EdmEntityType) ((UriResourceFunction) pathSegment).getType()
- : (EdmEntityType) ((UriResourceNavigation) pathSegment).getType();
- final List<String> keyPredicateNames = entityType.getKeyPredicateNames();
- Map<String, EdmKeyPropertyRef> edmKeys = new HashMap<String, EdmKeyPropertyRef>();
- for (EdmKeyPropertyRef key : entityType.getKeyPropertyRefs()) {
- edmKeys.put(key.getName(), key);
- final String alias = key.getAlias();
- if (alias != null) {
- edmKeys.put(alias, key);
- }
- }
-
- for (UriParameter keyPredicate : keyPredicates) {
- final String name = keyPredicate.getName();
- final String alias = keyPredicate.getAlias();
-
- if (keyPredicate.getReferencedProperty() == null) {
- final String value = alias == null ?
- keyPredicate.getText() :
- uriInfo.getValueForAlias(alias);
-
- EdmKeyPropertyRef edmKey = edmKeys.get(name);
- if (edmKey == null) {
- if (keyPredicateNames.contains(name)) {
- throw new UriValidationException("Double key property: " + name,
- UriValidationException.MessageKeys.DOUBLE_KEY_PROPERTY, name);
- } else {
- throw new UriValidationException("Unknown key property: " + name,
- UriValidationException.MessageKeys.INVALID_KEY_PROPERTY, name);
- }
- }
-
- final EdmProperty property = edmKey.getProperty();
- final EdmPrimitiveType edmPrimitiveType = (EdmPrimitiveType) property.getType();
- try {
- if (!edmPrimitiveType.validate(edmPrimitiveType.fromUriLiteral(value),
- property.isNullable(), property.getMaxLength(),
- property.getPrecision(), property.getScale(), property.isUnicode())) {
- throw new UriValidationException("PrimitiveTypeException",
- UriValidationException.MessageKeys.INVALID_KEY_PROPERTY, name);
- }
- } catch (EdmPrimitiveTypeException e) {
- throw new UriValidationException("PrimitiveTypeException", e,
- UriValidationException.MessageKeys.INVALID_KEY_PROPERTY, name);
- }
- }
-
- edmKeys.remove(name);
- edmKeys.remove(alias);
- }
- }
- }
- }
- }
-
- private boolean isEntityColFunction(final UriResource pathSegment) {
- if (pathSegment.getKind() == UriResourceKind.function) {
- final UriResourceFunction resourceFunction = (UriResourceFunction) pathSegment;
- final EdmReturnType returnType = resourceFunction.getFunction().getReturnType();
-
- return returnType.isCollection() && returnType.getType().getKind() == EdmTypeKind.ENTITY;
- } else {
- return false;
- }
- }
-
private void validatePropertyOperations(final UriInfo uriInfo, final HttpMethod method)
throws UriValidationException {
final List<UriResource> parts = uriInfo.getUriResourceParts();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties b/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
index 6bbad3b..ef5e744 100644
--- a/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
+++ b/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
@@ -89,6 +89,7 @@ UriValidationException.UNALLOWED_KIND_BEFORE_VALUE=The kind '%1$s' is not allowe
UriValidationException.UNALLOWED_KIND_BEFORE_COUNT=The kind '%1$s' is not allowed before '$count'.
UriValidationException.UNALLOWED_RESOURCE_PATH=The resource part '%1$s' is not allowed.
UriValidationException.MISSING_PARAMETER=Missing mandatory parameter '%1$s'.
+UriValidationException.MISSING_ALIAS=Missing alias '%1$s'.
ContentNegotiatorException.UNSUPPORTED_ACCEPT_TYPES=The content-type range '%1$s' is not supported as value of the Accept header.
ContentNegotiatorException.UNSUPPORTED_CONTENT_TYPE=The content type '%1$s' is not supported.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/UriInfoImplTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/UriInfoImplTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/UriInfoImplTest.java
index 68e6637..bdc2986 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/UriInfoImplTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/UriInfoImplTest.java
@@ -23,8 +23,6 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
-import java.util.Arrays;
-
import org.apache.olingo.commons.api.edm.EdmAction;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.ex.ODataRuntimeException;
@@ -122,31 +120,30 @@ public class UriInfoImplTest {
final QueryOption top = new TopOptionImpl().setName("");
final QueryOption levels = new LevelsOptionImpl().setName("");
- final QueryOption customOption0 = new CustomQueryOptionImpl().setName("").setText("A");
- final QueryOption customOption1 = new CustomQueryOptionImpl().setName("").setText("B");
+ final QueryOption customOption0 = new CustomQueryOptionImpl().setName("0").setText("A");
+ final QueryOption customOption1 = new CustomQueryOptionImpl().setName("1").setText("B");
final QueryOption initialQueryOption = new CustomQueryOptionImpl();
final QueryOption alias = new AliasQueryOptionImpl().setName("alias").setText("C");
final UriInfo uriInfo = new UriInfoImpl()
- .setQueryOptions(Arrays.asList(
- expand,
- filter,
- format,
- id,
- inlinecount,
- orderby,
- search,
- select,
- skip,
- skipToken,
- top,
- customOption0,
- customOption1,
- levels,
- initialQueryOption,
- alias));
+ .setQueryOption(expand)
+ .setQueryOption(filter)
+ .setQueryOption(format)
+ .setQueryOption(id)
+ .setQueryOption(inlinecount)
+ .setQueryOption(orderby)
+ .setQueryOption(search)
+ .setQueryOption(select)
+ .setQueryOption(skip)
+ .setQueryOption(skipToken)
+ .setQueryOption(top)
+ .setQueryOption(customOption0)
+ .setQueryOption(customOption1)
+ .setQueryOption(levels)
+ .setQueryOption(initialQueryOption)
+ .setQueryOption(alias);
assertEquals(12, uriInfo.getSystemQueryOptions().size());
assertEquals(expand, uriInfo.getExpandOption());
@@ -164,7 +161,7 @@ public class UriInfoImplTest {
assertArrayEquals(new QueryOption[] { alias }, uriInfo.getAliases().toArray());
assertEquals("C", uriInfo.getValueForAlias("alias"));
- assertArrayEquals(new QueryOption[] { customOption0, customOption1, initialQueryOption },
+ assertArrayEquals(new QueryOption[] { customOption0, customOption1 },
uriInfo.getCustomQueryOptions().toArray());
}
@@ -185,7 +182,6 @@ public class UriInfoImplTest {
@Test
public void alias() {
final UriInfo uriInfo = new UriInfoImpl()
- .addAlias((AliasQueryOption) new AliasQueryOptionImpl().setName("A").setText("notUsed"))
.addAlias((AliasQueryOption) new AliasQueryOptionImpl().setName("A").setText("X"))
.addAlias((AliasQueryOption) new AliasQueryOptionImpl().setName("B").setText("Y"))
.addAlias((AliasQueryOption) new AliasQueryOptionImpl().setName("C").setText("Z"));
@@ -199,4 +195,12 @@ public class UriInfoImplTest {
assertTrue(uriInfo.getSystemQueryOptions().isEmpty());
assertTrue(uriInfo.getCustomQueryOptions().isEmpty());
}
+
+ @Test(expected = ODataRuntimeException.class)
+ public void doubleAlias() {
+ final AliasQueryOption alias = (AliasQueryOption) new AliasQueryOptionImpl().setName("A");
+ new UriInfoImpl()
+ .addAlias(alias)
+ .addAlias(alias);
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/ExpressionParserTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/ExpressionParserTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/ExpressionParserTest.java
index a5fda50..1fce7b5 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/ExpressionParserTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/ExpressionParserTest.java
@@ -252,7 +252,7 @@ public class ExpressionParserTest {
private Expression parseExpression(final String expressionString)
throws UriParserException, UriValidationException {
UriTokenizer tokenizer = new UriTokenizer(expressionString);
- final Expression expression = new ExpressionParser(mock(Edm.class), odata).parse(tokenizer, null, null);
+ final Expression expression = new ExpressionParser(mock(Edm.class), odata).parse(tokenizer, null, null, null);
assertNotNull(expression);
assertTrue(tokenizer.next(TokenKind.EOF));
return expression;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/UriTokenizerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/UriTokenizerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/UriTokenizerTest.java
index 3ca49c8..118e2ea 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/UriTokenizerTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/UriTokenizerTest.java
@@ -371,6 +371,9 @@ public class UriTokenizerTest {
assertTrue(new UriTokenizer("{\"name\":null}").next(TokenKind.jsonArrayOrObject));
assertTrue(new UriTokenizer("{\"name\":\"value\"}").next(TokenKind.jsonArrayOrObject));
assertTrue(new UriTokenizer("{\"name\":\"value\",\"name2\":null}").next(TokenKind.jsonArrayOrObject));
+ assertFalse(new UriTokenizer("{\"name\"}").next(TokenKind.jsonArrayOrObject));
+ assertFalse(new UriTokenizer("{\"name\":}").next(TokenKind.jsonArrayOrObject));
+ assertFalse(new UriTokenizer("{0}").next(TokenKind.jsonArrayOrObject));
// array with values
assertTrue(new UriTokenizer("[]").next(TokenKind.jsonArrayOrObject));
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java
index 20cbf94..9dad2b9 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java
@@ -62,6 +62,7 @@ import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.uri.UriInfoResource;
import org.apache.olingo.server.api.uri.UriParameter;
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
+import org.apache.olingo.server.api.uri.queryoption.expression.Literal;
public class DataProvider {
@@ -104,7 +105,12 @@ public class DataProvider {
final EdmProperty property = (EdmProperty) edmEntityType.getProperty(key.getName());
final EdmPrimitiveType type = (EdmPrimitiveType) property.getType();
final Object value = entity.getProperty(key.getName()).getValue();
- final Object keyValue = type.valueOfString(type.fromUriLiteral(key.getText()),
+ if (key.getExpression() != null && !(key.getExpression() instanceof Literal)) {
+ throw new DataProviderException("Expression in key value is not supported yet!",
+ HttpStatusCode.NOT_IMPLEMENTED);
+ }
+ final String text = key.getAlias() == null ? key.getText() : ((Literal) key.getExpression()).getText();
+ final Object keyValue = type.valueOfString(type.fromUriLiteral(text),
property.isNullable(), property.getMaxLength(), property.getPrecision(), property.getScale(),
property.isUnicode(),
Calendar.class.isAssignableFrom(value.getClass()) ? Calendar.class : value.getClass());
@@ -540,6 +546,10 @@ public class DataProvider {
final List<UriParameter> parameters, final UriInfoResource uriInfo) throws DataProviderException {
Map<String, Parameter> values = new HashMap<String, Parameter>();
for (final UriParameter parameter : parameters) {
+ if (parameter.getExpression() != null && !(parameter.getExpression() instanceof Literal)) {
+ throw new DataProviderException("Expression in function-parameter value is not supported yet!",
+ HttpStatusCode.NOT_IMPLEMENTED);
+ }
final EdmParameter edmParameter = function.getParameter(parameter.getName());
final String text = parameter.getAlias() == null ?
parameter.getText() :
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/SystemQueryOptionsRuntimeException.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/SystemQueryOptionsRuntimeException.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/SystemQueryOptionsRuntimeException.java
index 469052d..9b74378 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/SystemQueryOptionsRuntimeException.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/SystemQueryOptionsRuntimeException.java
@@ -18,13 +18,14 @@
*/
package org.apache.olingo.server.tecsvc.processor.queryoptions.options;
+import org.apache.olingo.commons.api.ex.ODataException;
import org.apache.olingo.commons.api.ex.ODataRuntimeException;
public class SystemQueryOptionsRuntimeException extends ODataRuntimeException {
private static final long serialVersionUID = 1L;
- public SystemQueryOptionsRuntimeException(final Exception cause) {
+ public SystemQueryOptionsRuntimeException(final ODataException cause) {
super(cause);
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ContainerProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ContainerProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ContainerProvider.java
index 3fc164e..aeeb167 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ContainerProvider.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ContainerProvider.java
@@ -206,7 +206,7 @@ public class ContainerProvider {
.setAnnotations(Arrays.asList(
new CsdlAnnotation().setTerm("Core.Description")
.setExpression(new CsdlConstantExpression(CsdlConstantExpression.ConstantExpressionType.String)
- .setValue("Contains entities with two primitve types")),
+ .setValue("Contains entities with two primitive types")),
new CsdlAnnotation().setTerm(TermProvider.TERM_DATA.getFullQualifiedNameAsString()).setExpression(
new CsdlConstantExpression(CsdlConstantExpression.ConstantExpressionType.Bool, "true"))));
} else if (name.equals("ESMixPrimCollComp")) {
@@ -217,7 +217,7 @@ public class ContainerProvider {
new CsdlAnnotation().setTerm("Core.Description")
.setExpression(new CsdlConstantExpression(CsdlConstantExpression.ConstantExpressionType.String)
.setValue("Contains entities with various properties of type primitive, collection "
- + "of primitve, complex and collection of complex")),
+ + "of primitive, complex and collection of complex")),
new CsdlAnnotation().setTerm(TermProvider.TERM_DATA.getFullQualifiedNameAsString()).setExpression(
new CsdlConstantExpression(CsdlConstantExpression.ConstantExpressionType.Bool, "true"))));
@@ -609,7 +609,7 @@ public class ContainerProvider {
new CsdlAnnotation().setTerm("Core.Description")
.setExpression(new CsdlConstantExpression(CsdlConstantExpression.ConstantExpressionType.String)
.setValue("Contains entities with a complex type, "
- + "various nested primitve types and collections")),
+ + "various nested primitive types and collections")),
new CsdlAnnotation().setTerm(TermProvider.TERM_DATA.getFullQualifiedNameAsString()).setExpression(
new CsdlConstantExpression(CsdlConstantExpression.ConstantExpressionType.Bool, "true"))));
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/TestFullResourcePath.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/TestFullResourcePath.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/TestFullResourcePath.java
index 5a03676..fc9a0b8 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/TestFullResourcePath.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/TestFullResourcePath.java
@@ -53,13 +53,9 @@ public class TestFullResourcePath {
private static final OData oData = OData.newInstance();
private static final Edm edm = oData.createServiceMetadata(
new EdmTechProvider(), Collections.<EdmxReference> emptyList()).getEdm();
- private final TestUriValidator testUri;
- private final FilterValidator testFilter;
- public TestFullResourcePath() {
- testUri = new TestUriValidator().setEdm(edm);
- testFilter = new FilterValidator().setEdm(edm);
- }
+ private final TestUriValidator testUri = new TestUriValidator().setEdm(edm);
+ private final FilterValidator testFilter = new FilterValidator().setEdm(edm);
@Test
public void enumAndTypeDefAsKey() throws Exception {
@@ -1229,7 +1225,6 @@ public class TestFullResourcePath {
.isType(EntityTypeProvider.nameETTwoPrim, false)
.isTypeFilterOnCollection(EntityTypeProvider.nameETTwoBase)
.isKeyPredicate(0, "PropertyInt16", "-32768");
-
}
@Test
@@ -2062,15 +2057,6 @@ public class TestFullResourcePath {
}
@Test
- public void runFunctionImpEsAlias() throws Exception {
-
- testUri.run("FICRTCollESTwoKeyNavParam(ParameterInt16=@parameterAlias)", "@parameterAlias=1");
- testUri.run("FICRTCollESTwoKeyNavParam(ParameterInt16=@parameterAlias)/$count", "@parameterAlias=1");
- testUri.runEx("FICRTCollESTwoKeyNavParam(ParameterInt16=@invalidAlias)", "@validAlias=1")
- .isExValidation(UriValidationException.MessageKeys.MISSING_PARAMETER);
- }
-
- @Test
public void runFunctionImpEsCast() throws Exception {
testUri.run("FICRTCollESTwoKeyNavParam(ParameterInt16=1)/olingo.odata.test1.ETBaseTwoKeyNav")
@@ -2650,6 +2636,13 @@ public class TestFullResourcePath {
.n()
.isNavProperty("NavPropertyETTwoKeyNavOne", EntityTypeProvider.nameETTwoKeyNav, false);
+ testUri.run("ESTwoKeyNav", "$expand=olingo.odata.test1.ETBaseTwoKeyNav/PropertyCompNav/*")
+ .isKind(UriInfoKind.resource).goPath().first()
+ .goExpand().first()
+ .isExpandStartType(EntityTypeProvider.nameETBaseTwoKeyNav)
+ .isSegmentStar()
+ .goPath().last().isComplexProperty("PropertyCompNav", ComplexTypeProvider.nameCTBasePrimCompNav, false);
+
testUri.run("ESTwoKeyNav", "$expand=olingo.odata.test1.ETBaseTwoKeyNav/PropertyCompNav"
+ "/olingo.odata.test1.CTTwoBasePrimCompNav/NavPropertyETTwoKeyNavOne")
.isKind(UriInfoKind.resource).goPath().first()
@@ -2736,6 +2729,8 @@ public class TestFullResourcePath {
.isExSemantic(MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE);
testUri.runEx("ESTwoKeyNav", "$expand=PropertyCompNav/undefined")
.isExSemantic(MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE);
+ testUri.runEx("ESTwoKeyNav", "$expand=PropertyCompNav/*+")
+ .isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
}
@Test
@@ -2874,6 +2869,7 @@ public class TestFullResourcePath {
.isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
testUri.runEx("ESTwoKeyNav", "$select=olingo.odata.test1.1")
.isExSemantic(MessageKeys.UNKNOWN_PART);
+ testUri.runEx("ESTwoKeyNav", "$select=unknown_namespace.*").isExSemantic(MessageKeys.UNKNOWN_PART);
testUri.runEx("ESTwoKeyNav", "$select=olingo.odata.test1.ETKeyNav")
.isExSemantic(MessageKeys.INCOMPATIBLE_TYPE_FILTER);
testUri.runEx("ESTwoKeyNav", "$select=PropertyCompNav/olingo.odata.test1.CTTwoPrim")
@@ -3771,7 +3767,8 @@ public class TestFullResourcePath {
@Test
public void filterFunctions() throws Exception {
testFilter.runOnETAllPrim(
- "olingo.odata.test1.UFCRTETTwoKeyNavParamCTTwoPrim(ParameterCTTwoPrim=@ParamAlias) eq null")
+ "olingo.odata.test1.UFCRTETTwoKeyNavParamCTTwoPrim(ParameterCTTwoPrim=@ParamAlias) eq null"
+ + "&@ParamAlias={}")
.is("<<UFCRTETTwoKeyNavParamCTTwoPrim> eq <null>>")
.left().goPath()
.first()
@@ -3803,14 +3800,14 @@ public class TestFullResourcePath {
.n().isPrimitiveProperty("PropertyString", PropertyProvider.nameString, false);
testFilter.runOnETTwoKeyNav("PropertyComp/olingo.odata.test1.BFCCTPrimCompRTETTwoKeyNavParam"
- + "(ParameterString=null)/PropertyString eq 'SomeString'")
+ + "(ParameterString='1')/PropertyString eq 'SomeString'")
.is("<<PropertyComp/BFCCTPrimCompRTETTwoKeyNavParam/PropertyString> eq <'SomeString'>>")
.root().left().goPath()
.first()
.isComplexProperty("PropertyComp", ComplexTypeProvider.nameCTPrimComp, false)
.n()
.isFunction("BFCCTPrimCompRTETTwoKeyNavParam")
- .isParameter(0, "ParameterString", null)
+ .isParameter(0, "ParameterString", "'1'")
.n()
.isPrimitiveProperty("PropertyString", PropertyProvider.nameString, false);
@@ -3880,7 +3877,8 @@ public class TestFullResourcePath {
.isPrimitiveProperty("PropertyInt16", PropertyProvider.nameInt16, false);
testFilter.runOnETTwoKeyNav("olingo.odata.test1.UFCRTETTwoKeyNavParam(ParameterInt16=@Param1Alias)"
- + "/PropertyInt16 eq 2")
+ + "/PropertyInt16 eq 2"
+ + "&@Param1Alias=1")
.root().left().goPath()
.first()
.isFunction("UFCRTETTwoKeyNavParam")
@@ -3912,6 +3910,9 @@ public class TestFullResourcePath {
.n().isComplexProperty("PropertyComp", ComplexTypeProvider.nameCTPrimComp, false)
.n().isComplexProperty("PropertyComp", ComplexTypeProvider.nameCTAllPrim, false)
.n().isPrimitiveProperty("PropertyString", PropertyProvider.nameString, false);
+
+ testFilter.runOnETTwoKeyNavEx("olingo.odata.test1.UFCRTETTwoKeyNavParam(ParameterInt16=@alias)")
+ .isExValidation(UriValidationException.MessageKeys.MISSING_ALIAS);
}
@Test
@@ -4629,12 +4630,12 @@ public class TestFullResourcePath {
.goParameter(1).isTypedLiteral(EntityTypeProvider.nameETKeyPrimNav);
testFilter.runOnETAllPrim(
- "olingo.odata.test1.UFCRTCTTwoPrimTwoParam(ParameterInt16=null,ParameterString=null) ne null")
+ "olingo.odata.test1.UFCRTCTTwoPrimTwoParam(ParameterInt16=1,ParameterString='1') ne null")
.left()
.goPath()
.isFunction("UFCRTCTTwoPrimTwoParam")
- .isParameter(0, "ParameterInt16", null)
- .isParameter(1, "ParameterString", null);
+ .isParameter(0, "ParameterInt16", "1")
+ .isParameter(1, "ParameterString", "'1'");
testFilter.runOnETKeyNavEx("cast(NavPropertyETKeyPrimNavOne,olingo.odata.test1.ETKeyNav)")
.isExSemantic(MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE);
@@ -5023,21 +5024,24 @@ public class TestFullResourcePath {
.n().isPrimitiveProperty("PropertyDate", PropertyProvider.nameDate, false);
testFilter.runOrderByOnETTwoKeyNav("olingo.odata.test1.UFCRTETAllPrimTwoParam("
- + "ParameterString=@ParamStringAlias,ParameterInt16=@ParamInt16Alias)/PropertyString eq 'SomeString'")
+ + "ParameterString=@ParamStringAlias,ParameterInt16=@ParamInt16Alias)/PropertyString eq 'SomeString'"
+ + "&@ParamStringAlias='1'&@ParamInt16Alias=1")
.isSortOrder(0, false)
.goOrder(0).isBinary(BinaryOperatorKind.EQ).left().goPath()
.first().isFunction("UFCRTETAllPrimTwoParam").goUpFilterValidator()
.goOrder(0).right().isLiteral("'SomeString'");
testFilter.runOrderByOnETTwoKeyNav("olingo.odata.test1.UFCRTETAllPrimTwoParam("
- + "ParameterString=@ParamStringAlias,ParameterInt16=@ParamInt16Alias)/PropertyString eq 'SomeString' asc")
+ + "ParameterString=@ParamStringAlias,ParameterInt16=@ParamInt16Alias)/PropertyString eq 'SomeString' asc"
+ + "&@ParamStringAlias='1'&@ParamInt16Alias=1")
.isSortOrder(0, false)
.goOrder(0).isBinary(BinaryOperatorKind.EQ).left().goPath()
.first().isFunction("UFCRTETAllPrimTwoParam").goUpFilterValidator()
.goOrder(0).right().isLiteral("'SomeString'");
testFilter.runOrderByOnETTwoKeyNav("olingo.odata.test1.UFCRTETAllPrimTwoParam("
- + "ParameterString=@ParamStringAlias,ParameterInt16=@ParamInt16Alias)/PropertyString eq 'SomeString' desc")
+ + "ParameterString=@ParamStringAlias,ParameterInt16=@ParamInt16Alias)/PropertyString eq 'SomeString' desc"
+ + "&@ParamStringAlias='1'&@ParamInt16Alias=1")
.isSortOrder(0, true)
.goOrder(0).isBinary(BinaryOperatorKind.EQ).left().goPath()
.first().isFunction("UFCRTETAllPrimTwoParam").goUpFilterValidator()
@@ -5045,7 +5049,8 @@ public class TestFullResourcePath {
testFilter.runOrderByOnETTwoKeyNav("olingo.odata.test1.UFCRTETAllPrimTwoParam("
+ "ParameterString=@ParamStringAlias,ParameterInt16=@ParamInt16Alias)/PropertyString eq 'SomeString' desc,"
- + "PropertyString eq '1'")
+ + "PropertyString eq '1'"
+ + "&@ParamStringAlias='1'&@ParamInt16Alias=1")
.isSortOrder(0, true)
.goOrder(0).isBinary(BinaryOperatorKind.EQ).left().goPath()
.first().isFunction("UFCRTETAllPrimTwoParam").goUpFilterValidator()
@@ -5553,14 +5558,6 @@ public class TestFullResourcePath {
}
@Test
- public void alias() throws Exception {
- testUri.run("ESTwoKeyNav(PropertyInt16=1,PropertyString=@A)", "@A='2'").goPath()
- .isKeyPredicate(0, "PropertyInt16", "1")
- .isKeyPredicateAlias(1, "PropertyString", "@A")
- .isInAliasToValueMap("@A", "'2'");
- }
-
- @Test
public void doublePercentDecoding() throws Exception {
testUri.runEx("ESAllPrim%252832767%29").isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
}
@@ -5775,13 +5772,42 @@ public class TestFullResourcePath {
}
@Test
- public void parameterAliasLiteralValidation() throws Exception {
- testUri.run("ESAllPrim(PropertyInt16=@p1)", "@p1=1");
- testUri.run("ESAllPrim(PropertyInt16=@p1)", "@p1=-2");
- testUri.runEx("ESAllPrim(PropertyInt16=@p1)", "@p1='ewe'")
- .isExValidation(UriValidationException.MessageKeys.INVALID_KEY_PROPERTY);
+ public void alias() throws Exception {
+ testUri.run("ESTwoKeyNav(PropertyInt16=1,PropertyString=@A)", "@A='2'").goPath()
+ .isKeyPredicate(0, "PropertyInt16", "1")
+ .isKeyPredicateAlias(1, "PropertyString", "@A")
+ .isInAliasToValueMap("@A", "'2'");
+ testUri.run("ESAllPrim(PropertyInt16=@p1)", "@p1=1").goPath()
+ .isKeyPredicateAlias(0, "PropertyInt16", "@p1")
+ .isInAliasToValueMap("@p1", "1");
+ testUri.run("ESAllPrim(@p1)", "@p1=-2").goPath()
+ .isKeyPredicateAlias(0, "PropertyInt16", "@p1")
+ .isInAliasToValueMap("@p1", "-2");
+
+ testFilter.runOnETAllPrim("PropertyInt16 gt @alias&@alias=1")
+ .right().isAlias("@alias");
+ testFilter.runOnETAllPrim("@alias&@alias=@otherAlias&@otherAlias=true")
+ .isAlias("@alias");
+
+ testUri.runEx("ESAllPrim(@p1)")
+ .isExValidation(UriValidationException.MessageKeys.MISSING_ALIAS);
+ testUri.runEx("ESAllPrim(PropertyInt16=@p1)", "@p1='ewe'").isExSemantic(MessageKeys.UNKNOWN_PART);
testUri.runEx("ESAllPrim(PropertyInt16=@p1)", "@p1='ewe")
.isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
+ testFilter.runOnETKeyNavEx("PropertyInt16 gt @alias")
+ .isExValidation(UriValidationException.MessageKeys.MISSING_ALIAS);
+ testFilter.runOnETKeyNavEx("PropertyInt16 gt @alias&@alias=@alias")
+ .isExValidation(UriValidationException.MessageKeys.MISSING_ALIAS);
+ testFilter.runOnETKeyNavEx("@alias&@alias=@alias2&@alias2=true or @alias")
+ .isExValidation(UriValidationException.MessageKeys.MISSING_ALIAS);
+ }
+
+ @Test
+ public void functionImportParameterAlias() throws Exception {
+ testUri.run("FICRTCollESTwoKeyNavParam(ParameterInt16=@parameterAlias)", "@parameterAlias=1");
+ testUri.run("FICRTCollESTwoKeyNavParam(ParameterInt16=@parameterAlias)/$count", "@parameterAlias=1");
+ testUri.runEx("FICRTCollESTwoKeyNavParam(ParameterInt16=@invalidAlias)", "@validAlias=1")
+ .isExValidation(UriValidationException.MessageKeys.MISSING_ALIAS);
}
@Test
@@ -5854,10 +5880,10 @@ public class TestFullResourcePath {
.isExValidation(UriValidationException.MessageKeys.MISSING_PARAMETER);
testUri.runEx("FICRTCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test)")
- .isExValidation(UriValidationException.MessageKeys.MISSING_PARAMETER);
+ .isExValidation(UriValidationException.MessageKeys.MISSING_ALIAS);
testUri.runEx("FICRTCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test)", "@test=null")
- .isExValidation(UriValidationException.MessageKeys.MISSING_PARAMETER);
+ .isExValidation(UriValidationException.MessageKeys.MISSING_ALIAS);
testUri.run("FICRTCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test)", "@test='null'");
@@ -5881,7 +5907,7 @@ public class TestFullResourcePath {
testUri.runEx("ESTwoKeyNav", "$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
+ "(ParameterComp=@p1) eq '0'&@p1={\"PropertyInt16\":1,\"PropertyString\":\"1\"}}")
- .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
+ .isExSemantic(MessageKeys.UNKNOWN_PART);
testUri.runEx("ESTwoKeyNav", "$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
+ "(ParameterComp=@p1) eq '0'&@p1={\"PropertyInt16\":[1,2,3]],\"PropertyString\":\"1\"}")
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/queryoption/QueryOptionTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/queryoption/QueryOptionTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/queryoption/QueryOptionTest.java
index c3d90c9..4643283 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/queryoption/QueryOptionTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/queryoption/QueryOptionTest.java
@@ -132,7 +132,7 @@ public class QueryOptionTest {
FilterOptionImpl option = new FilterOptionImpl();
assertEquals(SystemQueryOptionKind.FILTER, option.getKind());
- AliasImpl expression = new AliasImpl(null);
+ AliasImpl expression = new AliasImpl(null, null);
option.setExpression(expression);
assertEquals(expression, option.getExpression());
@@ -184,7 +184,7 @@ public class QueryOptionTest {
public void testOrderByItemImpl() {
OrderByItemImpl option = new OrderByItemImpl();
- AliasImpl expression = new AliasImpl(null);
+ AliasImpl expression = new AliasImpl(null, null);
option.setExpression(expression);
assertEquals(expression, option.getExpression());
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/queryoption/expression/ExpressionTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/queryoption/expression/ExpressionTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/queryoption/expression/ExpressionTest.java
index fad718b..66528a0 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/queryoption/expression/ExpressionTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/queryoption/expression/ExpressionTest.java
@@ -70,12 +70,12 @@ public class ExpressionTest {
@Test
public void aliasExpression() throws Exception {
- AliasImpl expression = new AliasImpl("Test");
+ AliasImpl expression = new AliasImpl("@Test", null);
- assertEquals("Test", expression.getParameterName());
+ assertEquals("@Test", expression.getParameterName());
String output = expression.accept(new FilterTreeToText());
- assertEquals("<Test>", output);
+ assertEquals("<@Test>", output);
}
@Test
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterValidator.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterValidator.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterValidator.java
index 161299c..600a2bd 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterValidator.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterValidator.java
@@ -36,6 +36,7 @@ import org.apache.olingo.server.api.uri.UriInfoKind;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.queryoption.FilterOption;
import org.apache.olingo.server.api.uri.queryoption.OrderByOption;
+import org.apache.olingo.server.api.uri.queryoption.expression.Alias;
import org.apache.olingo.server.api.uri.queryoption.expression.Binary;
import org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKind;
import org.apache.olingo.server.api.uri.queryoption.expression.Enumeration;
@@ -102,11 +103,6 @@ public class FilterValidator implements TestValidator {
return this;
}
- public FilterValidator setOrderBy(final OrderByOption orderBy) {
- this.orderBy = orderBy;
- return this;
- }
-
public FilterValidator setExpression(final Expression expression) {
rootExpression = curExpression = expression;
return this;
@@ -189,10 +185,7 @@ public class FilterValidator implements TestValidator {
public FilterValidator runUri(final String path, final String query)
throws UriParserException, UriValidationException {
- Parser parser = new Parser(edm, odata);
- UriInfo uriInfo = null;
-
- uriInfo = parser.parseUri(path, query, null);
+ final UriInfo uriInfo = new Parser(edm, odata).parseUri(path, query, null);
if (uriInfo.getKind() != UriInfoKind.resource) {
fail("Filtervalidator can only be used on resourcePaths");
@@ -224,7 +217,7 @@ public class FilterValidator implements TestValidator {
fail("Filtervalidator can only be used on resourcePaths");
}
- setOrderBy(uriInfo.getOrderByOption());
+ orderBy = uriInfo.getOrderByOption();
return this;
}
@@ -323,6 +316,11 @@ public class FilterValidator implements TestValidator {
return this;
}
+ public FilterValidator root() {
+ curExpression = filter == null ? rootExpression : filter.getExpression();
+ return this;
+ }
+
public FilterValidator left() {
if (!(curExpression instanceof Binary)) {
fail("Current expression not a binary operator");
@@ -332,11 +330,6 @@ public class FilterValidator implements TestValidator {
return this;
}
- public FilterValidator root() {
- curExpression = filter == null ? rootExpression : filter.getExpression();
- return this;
- }
-
public FilterValidator right() {
if (!(curExpression instanceof Binary)) {
fail("Current expression is not a binary operator");
@@ -360,7 +353,7 @@ public class FilterValidator implements TestValidator {
if (!(curExpression instanceof Literal)) {
fail("Current expression is not a literal");
}
-
+
final EdmType type = ((Literal) curExpression).getType();
assertNotNull(type);
assertEquals(edmType, type);
@@ -448,7 +441,7 @@ public class FilterValidator implements TestValidator {
return this;
}
- public FilterValidator isEnum(final FullQualifiedName nameenstring, final List<String> enumValues) {
+ public FilterValidator isEnum(final FullQualifiedName name, final List<String> enumValues) {
if (!(curExpression instanceof Enumeration)) {
fail("Current expression not a enumeration");
}
@@ -456,18 +449,24 @@ public class FilterValidator implements TestValidator {
Enumeration enumeration = (Enumeration) curExpression;
// check name
- assertEquals(nameenstring, enumeration.getType().getFullQualifiedName());
+ assertEquals(name, enumeration.getType().getFullQualifiedName());
// check values
- int i = 0;
- for (String item : enumValues) {
- assertEquals(item, enumeration.getValues().get(i));
- i++;
- }
+ assertEquals(enumValues, enumeration.getValues());
return this;
}
+ public FilterValidator isAlias(final String name) {
+ if (curExpression instanceof Alias) {
+ final Alias alias = (Alias) curExpression;
+ assertEquals(name, alias.getParameterName());
+ } else {
+ fail("Current expression is not an alias.");
+ }
+ return this;
+ }
+
public FilterValidator isSortOrder(final int index, final boolean descending) {
assertEquals(descending, orderBy.getOrders().get(index).isDescending());
return this;
@@ -489,4 +488,10 @@ public class FilterValidator implements TestValidator {
assertEquals(messageKey, exception.getMessageKey());
return this;
}
+
+ public FilterValidator isExValidation(final UriValidationException.MessageKeys messageKey) {
+ assertEquals(UriValidationException.class, exception.getClass());
+ assertEquals(messageKey, exception.getMessageKey());
+ return this;
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/validator/UriValidatorTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/validator/UriValidatorTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/validator/UriValidatorTest.java
index 673b8ff..3d5e97f 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/validator/UriValidatorTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/validator/UriValidatorTest.java
@@ -30,7 +30,6 @@ import org.apache.olingo.server.api.edmx.EdmxReference;
import org.apache.olingo.server.core.uri.parser.Parser;
import org.apache.olingo.server.core.uri.parser.UriParserException;
import org.apache.olingo.server.core.uri.parser.UriParserSemanticException;
-import org.apache.olingo.server.core.uri.parser.UriParserSyntaxException;
import org.apache.olingo.server.core.uri.testutil.TestUriValidator;
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
import org.junit.Test;
@@ -118,7 +117,7 @@ public class UriValidatorTest {
{ URI_REFERENCES, QO_FILTER }, { URI_REFERENCES, QO_FORMAT }, { URI_REFERENCES, QO_ORDERBY },
{ URI_REFERENCES, QO_SEARCH }, { URI_REFERENCES, QO_SKIP }, { URI_REFERENCES, QO_SKIPTOKEN },
- { URI_REFERENCES, QO_TOP }, { URI_REFERENCES, QO_ID }, { URI_REFERENCES, QO_COUNT },
+ { URI_REFERENCES, QO_TOP }, { URI_REFERENCES, QO_COUNT },
{ URI_REFERENCE, QO_FORMAT },
@@ -204,7 +203,7 @@ public class UriValidatorTest {
{ URI_MEDIA_STREAM, QO_SEARCH }, { URI_MEDIA_STREAM, QO_SELECT }, { URI_MEDIA_STREAM, QO_SKIP },
{ URI_MEDIA_STREAM, QO_SKIPTOKEN }, { URI_MEDIA_STREAM, QO_TOP },
- { URI_REFERENCES, QO_EXPAND }, { URI_REFERENCES, QO_SELECT },
+ { URI_REFERENCES, QO_ID }, { URI_REFERENCES, QO_EXPAND }, { URI_REFERENCES, QO_SELECT },
{ URI_REFERENCE, QO_FILTER }, { URI_REFERENCE, QO_ID }, { URI_REFERENCE, QO_EXPAND },
{ URI_REFERENCE, QO_COUNT }, { URI_REFERENCE, QO_ORDERBY }, { URI_REFERENCE, QO_SEARCH },
@@ -328,22 +327,18 @@ public class UriValidatorTest {
new EdmTechProvider(), Collections.<EdmxReference> emptyList()).getEdm();
@Test
- public void serviceDocumentMustNotFailForHttpPostPutPatchDelete() throws Exception {
- // We must not fail with a nullpointer here as the HTTP method to resource validation happens in the dispatcher
- validate(URI_SERVICE, null, HttpMethod.GET);
- validate(URI_SERVICE, null, HttpMethod.POST);
- validate(URI_SERVICE, null, HttpMethod.PUT);
- validate(URI_SERVICE, null, HttpMethod.DELETE);
- validate(URI_SERVICE, null, HttpMethod.PATCH);
+ public void serviceDocumentMustNotFailForAllHttpMethods() throws Exception {
+ // We must not fail with a nullpointer here as the HTTP method to resource validation happens in the dispatcher.
+ for (final HttpMethod method : HttpMethod.values()) {
+ validate(URI_SERVICE, null, method);
+ }
}
@Test
public void validateForHttpMethods() throws Exception {
- validate(URI_ENTITY, null, HttpMethod.GET);
- validate(URI_ENTITY, null, HttpMethod.POST);
- validate(URI_ENTITY, null, HttpMethod.PUT);
- validate(URI_ENTITY, null, HttpMethod.DELETE);
- validate(URI_ENTITY, null, HttpMethod.PATCH);
+ for (final HttpMethod method : HttpMethod.values()) {
+ validate(URI_ENTITY, null, method);
+ }
}
@Test
@@ -378,45 +373,6 @@ public class UriValidatorTest {
}
@Test
- public void validateSelect() throws Exception {
- new TestUriValidator().setEdm(edm).run(URI_ENTITY, "$select=PropertyString");
- }
-
- @Test
- public void validateOrderBy() throws Exception {
- final TestUriValidator testUri = new TestUriValidator().setEdm(edm);
-
- testUri.run(URI_ENTITY_SET, "$orderby=PropertyString");
-
- testUri.runEx(URI_ENTITY, "$orderby=XXXX")
- .isExSemantic(UriParserSemanticException.MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE);
- }
-
- @Test
- public void validateCountInvalid() throws Exception {
- new TestUriValidator().setEdm(edm).runEx(URI_ENTITY_SET, "$count=foo")
- .isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
- }
-
- @Test
- public void validateTopInvalid() throws Exception {
- new TestUriValidator().setEdm(edm).runEx(URI_ENTITY_SET, "$top=foo")
- .isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
- }
-
- @Test
- public void validateSkipInvalid() throws Exception {
- new TestUriValidator().setEdm(edm).runEx(URI_ENTITY_SET, "$skip=foo")
- .isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
- }
-
- @Test
- public void validateDoubleSystemOptions() throws Exception {
- new TestUriValidator().setEdm(edm).runEx(URI_ENTITY_SET, "$skip=1&$skip=2")
- .isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
- }
-
- @Test
public void checkKeys() throws Exception {
final TestUriValidator testUri = new TestUriValidator().setEdm(edm);
@@ -502,9 +458,9 @@ public class UriValidatorTest {
try {
new UriValidator().validate(new Parser(edm, odata).parseUri(path, query, null), method);
} catch (final UriParserException e) {
- fail("Failed for uri: " + path + '?' + query);
+ fail("Failed for " + method + " on URI: " + path + '?' + query);
} catch (final UriValidationException e) {
- fail("Failed for uri: " + path + '?' + query);
+ fail("Failed for " + method + " on URI: " + path + '?' + query);
}
}
[11/22] olingo-odata4 git commit: OLINGO-862: MediaEntity Type:
HasStream is not inherited
Posted by mi...@apache.org.
OLINGO-862: MediaEntity Type: HasStream is not inherited
Signed-off-by: Christian Amend <ch...@sap.com>
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/53065cdf
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/53065cdf
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/53065cdf
Branch: refs/heads/OLINGO-832_StreamSerializerPoC
Commit: 53065cdface25971ef50a7b97febf54c7e69c623
Parents: 5d7c128
Author: Frederik Zimmer <fr...@partake.de>
Authored: Tue Feb 2 12:29:49 2016 +0100
Committer: Christian Amend <ch...@sap.com>
Committed: Thu Feb 4 15:12:40 2016 +0100
----------------------------------------------------------------------
.../commons/core/edm/EdmEntityTypeImpl.java | 7 ++++++-
.../core/edm/provider/EdmEntityTypeImplTest.java | 19 +++++++++++++++++++
2 files changed, 25 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/53065cdf/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEntityTypeImpl.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEntityTypeImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEntityTypeImpl.java
index 6d60afb..c532cb3 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEntityTypeImpl.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEntityTypeImpl.java
@@ -136,6 +136,11 @@ public class EdmEntityTypeImpl extends AbstractEdmStructuredType implements EdmE
@Override
public boolean hasStream() {
- return hasStream;
+ checkBaseType();
+
+ if (hasStream || entityBaseType != null && entityBaseType.hasStream()) {
+ return true;
+ }
+ return false;
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/53065cdf/lib/commons-core/src/test/java/org/apache/olingo/server/core/edm/provider/EdmEntityTypeImplTest.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/test/java/org/apache/olingo/server/core/edm/provider/EdmEntityTypeImplTest.java b/lib/commons-core/src/test/java/org/apache/olingo/server/core/edm/provider/EdmEntityTypeImplTest.java
index 6cbabff..d0013a2 100644
--- a/lib/commons-core/src/test/java/org/apache/olingo/server/core/edm/provider/EdmEntityTypeImplTest.java
+++ b/lib/commons-core/src/test/java/org/apache/olingo/server/core/edm/provider/EdmEntityTypeImplTest.java
@@ -241,6 +241,25 @@ public class EdmEntityTypeImplTest {
}
@Test
+ public void hasStreamInherited() throws Exception {
+ CsdlEdmProvider provider = mock(CsdlEdmProvider.class);
+ EdmProviderImpl edm = new EdmProviderImpl(provider);
+
+ FullQualifiedName baseName = new FullQualifiedName("namespace", "BaseTypeName");
+ CsdlEntityType baseType = new CsdlEntityType();
+ baseType.setHasStream(true);
+ when(provider.getEntityType(baseName)).thenReturn(baseType);
+
+ FullQualifiedName typeName = new FullQualifiedName("namespace", "typeName");
+ CsdlEntityType type = new CsdlEntityType();
+ type.setBaseType(baseName);
+ EdmEntityType typeWithBaseTypeWithStream = new EdmEntityTypeImpl(edm, typeName, type);
+ when(provider.getEntityType(typeName)).thenReturn(type);
+
+ assertTrue(typeWithBaseTypeWithStream.hasStream());
+ }
+
+ @Test
public void complexKeyWithAlias() {
List<String> keyPredicateNames = typeWithComplexKey.getKeyPredicateNames();
assertEquals(2, keyPredicateNames.size());
[21/22] olingo-odata4 git commit: Merge branch 'OLINGO-864'
Posted by mi...@apache.org.
Merge branch 'OLINGO-864'
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/3c205f90
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/3c205f90
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/3c205f90
Branch: refs/heads/OLINGO-832_StreamSerializerPoC
Commit: 3c205f907e129fba303a283ff4f8ac9c094e768a
Parents: 187c229 7b26cc6
Author: Ramesh Reddy <ra...@jboss.org>
Authored: Fri Feb 12 09:23:09 2016 -0600
Committer: Ramesh Reddy <ra...@jboss.org>
Committed: Fri Feb 12 09:23:09 2016 -0600
----------------------------------------------------------------------
.../client/AbstractParamTecSvcITCase.java | 14 +++++
.../commons/core/edm/primitivetype/EdmDate.java | 5 +-
.../edm/primitivetype/EdmDateTimeOffset.java | 62 ++++++++++++--------
.../core/edm/primitivetype/EdmTimeOfDay.java | 20 ++-----
.../core/edm/primitivetype/EdmDateTest.java | 1 -
.../primitivetype/EdmDateTimeOffsetTest.java | 9 ++-
.../edm/primitivetype/EdmTimeOfDayTest.java | 23 ++++++--
.../olingo/server/tecsvc/data/DataCreator.java | 10 +++-
.../server/tecsvc/data/DataProviderTest.java | 14 +++++
.../json/ODataJsonSerializerTest.java | 13 ++++
10 files changed, 116 insertions(+), 55 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3c205f90/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3c205f90/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
----------------------------------------------------------------------
[20/22] olingo-odata4 git commit: OLINGO-880: Enable MetadataParser
to load core vocabularies based on a perference setting,
these are loaded loaded from local classpath, instead of making a web call
Posted by mi...@apache.org.
OLINGO-880: Enable MetadataParser to load core vocabularies based on a perference setting, these are loaded loaded from local classpath, instead of making a web call
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/187c229b
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/187c229b
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/187c229b
Branch: refs/heads/OLINGO-832_StreamSerializerPoC
Commit: 187c229b6022923a028e6fe5a29a430e06003ff7
Parents: 801899a
Author: Ramesh Reddy <ra...@jboss.org>
Authored: Fri Feb 12 09:16:00 2016 -0600
Committer: Ramesh Reddy <ra...@jboss.org>
Committed: Fri Feb 12 09:16:00 2016 -0600
----------------------------------------------------------------------
.../olingo/server/core/MetadataParser.java | 118 +++---
.../olingo/server/core/ReferenceResolver.java | 3 +-
.../server/core/SchemaBasedEdmProvider.java | 39 +-
.../resources/Org.OData.Capabilities.V1.xml | 388 +++++++++++++++++++
.../src/main/resources/Org.OData.Core.V1.xml | 187 +++++++++
.../main/resources/Org.OData.Measures.V1.xml | 110 ++++++
.../core/MetadataParserAnnotationsTest.java | 11 +-
.../olingo/server/core/MetadataParserTest.java | 2 +-
.../olingo/server/example/TripPinServlet.java | 2 +
.../src/test/resources/annotations.xml | 2 +-
10 files changed, 807 insertions(+), 55 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/187c229b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
index b564792..03a6675 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
@@ -19,6 +19,7 @@
package org.apache.olingo.server.core;
import java.io.IOException;
+import java.io.InputStream;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URI;
@@ -95,38 +96,68 @@ import org.apache.olingo.server.api.edmx.EdmxReferenceIncludeAnnotation;
*/
public class MetadataParser {
private boolean parseAnnotations = false;
- private final String XML_LINK_NS = "http://www.w3.org/1999/xlink";
- private ReferenceResolver referenceResolver = new DefaultReferenceResolver();
+ private static final String XML_LINK_NS = "http://www.w3.org/1999/xlink";
+ private ReferenceResolver defaultReferenceResolver = new DefaultReferenceResolver();
+ private boolean loadCoreVocabularies = false;
- public void setParseAnnotations(boolean f) {
- this.parseAnnotations = true;
+ public MetadataParser parseAnnotations(boolean parse) {
+ this.parseAnnotations = parse;
+ return this;
}
- public void setReferenceResolver(ReferenceResolver resolver) {
- this.referenceResolver = resolver;
+ public MetadataParser referenceResolver(ReferenceResolver resolver) {
+ this.defaultReferenceResolver = resolver;
+ return this;
+ }
+
+ public MetadataParser loadCoreVocabularies(boolean load) {
+ this.loadCoreVocabularies = load;
+ return this;
}
public ServiceMetadata buildServiceMetadata(Reader csdl) throws XMLStreamException {
+ SchemaBasedEdmProvider provider = buildEdmProvider(csdl,
+ this.defaultReferenceResolver, this.loadCoreVocabularies);
+ return new ServiceMetadataImpl(provider, provider.getReferences(), null);
+ }
+
+ public SchemaBasedEdmProvider buildEdmProvider(Reader csdl) throws XMLStreamException {
+ return buildEdmProvider(csdl, this.defaultReferenceResolver, this.loadCoreVocabularies);
+ }
+
+ protected SchemaBasedEdmProvider buildEdmProvider(Reader csdl,
+ ReferenceResolver referenceResolver, boolean loadCoreVocabularies) throws XMLStreamException {
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
XMLEventReader reader = xmlInputFactory.createXMLEventReader(csdl);
-
+ return buildEdmProvider(reader, referenceResolver, loadCoreVocabularies);
+ }
+
+ protected SchemaBasedEdmProvider buildEdmProvider(InputStream csdl,
+ ReferenceResolver referenceResolver, boolean loadCoreVocabularies) throws XMLStreamException {
+ XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
+ XMLEventReader reader = xmlInputFactory.createXMLEventReader(csdl);
+ return buildEdmProvider(reader, referenceResolver, loadCoreVocabularies);
+ }
+
+ protected SchemaBasedEdmProvider buildEdmProvider(XMLEventReader reader,
+ ReferenceResolver referenceResolver, boolean loadCoreVocabularies) throws XMLStreamException {
SchemaBasedEdmProvider provider = new SchemaBasedEdmProvider(referenceResolver);
- final ArrayList<EdmxReference> references = new ArrayList<EdmxReference>();
-
new ElementReader<SchemaBasedEdmProvider>() {
@Override
void build(XMLEventReader reader, StartElement element, SchemaBasedEdmProvider provider,
String name) throws XMLStreamException {
- String version = attr(element, "Version");
String xmlBase = attrNS(element, XML_LINK_NS, "base");
- provider.setXMLBase(xmlBase);
+ provider.setXMLBase(xmlBase);
+ String version = attr(element, "Version");
if ("4.0".equals(version)) {
- readDataServicesAndReference(reader, element, provider, references);
+ readDataServicesAndReference(reader, element, provider);
} else {
throw new XMLStreamException("Currently only V4 is supported.");
}
}
}.read(reader, null, provider, "Edmx");
+
+ // make sure there is nothing left to read, due to parser error
if(reader.hasNext()) {
XMLEvent event = reader.peek();
throw new XMLStreamException(
@@ -135,34 +166,33 @@ public class MetadataParser {
event.asStartElement().getName().getLocalPart() :
event.asEndElement().getName().getLocalPart()));
}
- provider.addReferences(references);
- return new ServiceMetadataImpl(provider, references, null);
- }
-
- SchemaBasedEdmProvider buildEdmProvider(Reader csdl) throws XMLStreamException {
- XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
- XMLEventReader reader = xmlInputFactory.createXMLEventReader(csdl);
- return buildEdmProvider(reader);
- }
+
+ // load the core vocabularies
+ if (loadCoreVocabularies) {
+ loadVocabularySchema(provider, "Org.OData.Core.V1", "Org.OData.Core.V1.xml");
+ loadVocabularySchema(provider, "Org.OData.Capabilities.V1", "Org.OData.Capabilities.V1.xml");
+ loadVocabularySchema(provider, "Org.OData.Measures.V1", "Org.OData.Measures.V1.xml");
+ }
+ return provider;
+ }
- SchemaBasedEdmProvider buildEdmProvider(XMLEventReader reader) throws XMLStreamException {
- SchemaBasedEdmProvider provider = new SchemaBasedEdmProvider(this.referenceResolver);
- new ElementReader<SchemaBasedEdmProvider>() {
- @Override
- void build(XMLEventReader reader, StartElement element, SchemaBasedEdmProvider provider,
- String name) throws XMLStreamException {
- String version = attr(element, "Version");
- if ("4.0".equals(version)) {
- readDataServicesAndReference(reader, element, provider, new ArrayList<EdmxReference>());
- }
+ private void loadVocabularySchema(SchemaBasedEdmProvider provider, String namespace,
+ String resource) throws XMLStreamException {
+ CsdlSchema schema = provider.getSchema(namespace, false);
+ if (schema == null) {
+ InputStream is = this.getClass().getClassLoader().getResourceAsStream(resource);
+ if (is != null) {
+ SchemaBasedEdmProvider childProvider = buildEdmProvider(is, null, false);
+ provider.addSchema(childProvider.getSchema(namespace, false));
+ } else {
+ throw new XMLStreamException("failed to load "+resource+" core vocabulary");
}
- }.read(reader, null, provider, "Edmx");
- return provider;
+ }
}
private void readDataServicesAndReference(XMLEventReader reader,
- StartElement element, SchemaBasedEdmProvider provider,
- final ArrayList<EdmxReference> references) throws XMLStreamException {
+ StartElement element, SchemaBasedEdmProvider provider) throws XMLStreamException {
+ final ArrayList<EdmxReference> references = new ArrayList<EdmxReference>();
new ElementReader<SchemaBasedEdmProvider>() {
@Override
void build(XMLEventReader reader, StartElement element, SchemaBasedEdmProvider provider,
@@ -174,6 +204,7 @@ public class MetadataParser {
}
}
}.read(reader, element, provider, "DataServices", "Reference");
+ provider.addReferences(references);
}
private void readReference(XMLEventReader reader, StartElement element,
@@ -782,7 +813,7 @@ public class MetadataParser {
return property;
}
- private String attr(StartElement element, String name) {
+ private static String attr(StartElement element, String name) {
Attribute attr = element.getAttributeByName(new QName(name));
if (attr != null) {
return attr.getValue();
@@ -790,7 +821,7 @@ public class MetadataParser {
return null;
}
- private String attrNS(StartElement element, String ns, String name) {
+ private static String attrNS(StartElement element, String ns, String name) {
Attribute attr = element.getAttributeByName(new QName(ns, name));
if (attr != null) {
return attr.getValue();
@@ -1043,9 +1074,9 @@ public class MetadataParser {
throws XMLStreamException;
}
- class DefaultReferenceResolver implements ReferenceResolver{
+ private static class DefaultReferenceResolver implements ReferenceResolver {
@Override
- public SchemaBasedEdmProvider resolveReference(URI referenceUri, String xmlBase) {
+ public InputStream resolveReference(URI referenceUri, String xmlBase) {
URL schemaURL = null;
try {
if (referenceUri.isAbsolute()) {
@@ -1057,17 +1088,12 @@ public class MetadataParser {
throw new EdmException("No xml:base set to read the references from the metadata");
}
}
-
- XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
- XMLEventReader reader = xmlInputFactory.createXMLEventReader(schemaURL.openStream());
- return buildEdmProvider(reader);
+ return schemaURL.openStream();
} catch (MalformedURLException e) {
throw new EdmException(e);
- } catch (XMLStreamException e) {
- throw new EdmException(e);
} catch (IOException e) {
throw new EdmException(e);
}
}
- }
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/187c229b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ReferenceResolver.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ReferenceResolver.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ReferenceResolver.java
index f7d5101..2ac79bc 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ReferenceResolver.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ReferenceResolver.java
@@ -18,6 +18,7 @@
*/
package org.apache.olingo.server.core;
+import java.io.InputStream;
import java.net.URI;
public interface ReferenceResolver {
@@ -28,5 +29,5 @@ public interface ReferenceResolver {
* @param xmlBase xml:base if provided by the metadata document; null otherwise
* @return
*/
- SchemaBasedEdmProvider resolveReference(URI referenceUri, String xmlBase);
+ InputStream resolveReference(URI referenceUri, String xmlBase);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/187c229b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/SchemaBasedEdmProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/SchemaBasedEdmProvider.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/SchemaBasedEdmProvider.java
index a2f23f6..a778e2c 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/SchemaBasedEdmProvider.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/SchemaBasedEdmProvider.java
@@ -18,11 +18,15 @@
*/
package org.apache.olingo.server.core;
+import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import javax.xml.stream.XMLStreamException;
+
+import org.apache.olingo.commons.api.edm.EdmException;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.provider.CsdlAction;
import org.apache.olingo.commons.api.edm.provider.CsdlActionImport;
@@ -60,14 +64,25 @@ public class SchemaBasedEdmProvider implements CsdlEdmProvider {
void addSchema(CsdlSchema schema) {
this.edmSchemas.add(schema);
}
+
+ List<EdmxReference> getReferences(){
+ return new ArrayList<EdmxReference>(references.values());
+ }
- private CsdlSchema getSchema(String ns) {
+ CsdlSchema getSchema(String ns) {
+ return getSchema(ns, true);
+ }
+
+ CsdlSchema getSchema(String ns, boolean checkReferences) {
for (CsdlSchema s : this.edmSchemas) {
if (s.getNamespace().equals(ns)) {
return s;
}
}
- return getReferenceSchema(ns);
+ if (checkReferences) {
+ return getReferenceSchema(ns);
+ }
+ return null;
}
private CsdlSchema getReferenceSchema(String ns) {
@@ -77,7 +92,23 @@ public class SchemaBasedEdmProvider implements CsdlEdmProvider {
if (this.referenceSchemas.get(ns) == null) {
EdmxReference reference = this.references.get(ns);
if (reference != null) {
- SchemaBasedEdmProvider provider = this.referenceResolver.resolveReference(reference.getUri(), xmlBase);
+ SchemaBasedEdmProvider provider = null;
+ if (this.referenceResolver == null) {
+ throw new EdmException("Failed to load Reference "+reference.getUri());
+ } else {
+ InputStream is = this.referenceResolver.resolveReference(reference.getUri(), this.xmlBase);
+ if (is != null) {
+ try {
+ MetadataParser parser = new MetadataParser();
+ provider = parser.buildEdmProvider(is, this.referenceResolver, false);
+ } catch (XMLStreamException e) {
+ throw new EdmException("Failed to load Reference "+reference.getUri()+" parsing failed");
+ }
+ } else {
+ throw new EdmException("Failed to load Reference "+reference.getUri()+" loading failed");
+ }
+ }
+ // copy references
for (EdmxReferenceInclude include : reference.getIncludes()) {
this.referenceSchemas.put(include.getNamespace(), provider);
if (include.getAlias() != null) {
@@ -381,5 +412,5 @@ public class SchemaBasedEdmProvider implements CsdlEdmProvider {
this.xmlBase = base+"/";
}
}
- }
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/187c229b/lib/server-core-ext/src/main/resources/Org.OData.Capabilities.V1.xml
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/resources/Org.OData.Capabilities.V1.xml b/lib/server-core-ext/src/main/resources/Org.OData.Capabilities.V1.xml
new file mode 100644
index 0000000..991a0ae
--- /dev/null
+++ b/lib/server-core-ext/src/main/resources/Org.OData.Capabilities.V1.xml
@@ -0,0 +1,388 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+<!--
+
+ OData Version 4.0 Plus Errata 02
+ OASIS Standard incorporating Approved Errata 02
+ 30 October 2014
+ Copyright (c) OASIS Open 2014. All Rights Reserved.
+ Source: http://docs.oasis-open.org/odata/odata/v4.0/errata02/os/complete/vocabularies/
+
+-->
+<!--
+
+Technical Committee:
+ OASIS Open Data Protocol (OData) TC
+ https://www.oasis-open.org/committees/odata
+
+Chairs:
+ - Barbara Hartel (barbara.hartel@sap.com), SAP AG
+ - Ram Jeyaraman (Ram.Jeyaraman@microsoft.com), Microsoft
+
+Editors:
+ - Ralf Handl (ralf.handl@sap.com), SAP AG
+ - Michael Pizzo (mikep@microsoft.com), Microsoft
+ - Martin Zurmuehl (martin.zurmuehl@sap.com), SAP AG
+
+Additional artifacts:
+ This CSDL document is one component of a Work Product which consists of:
+ - OData Version 4.0 Part 1: Protocol
+ - OData Version 4.0 Part 2: URL Conventions
+ - OData Version 4.0 Part 3: Common Schema Definition Language (CSDL)
+ - OData ABNF Construction Rules Version 4.0
+ - OData ABNF Test Cases
+ - OData Core Vocabulary
+ - OData Capabilities Vocabulary (this document)
+ - OData Measures Vocabulary
+ - OData Metadata Service Entity Model
+ - OData EDMX XML Schema
+ - OData EDM XML Schema
+
+Related work:
+ This work product is related to the following two Work Products, each of
+ which define alternate formats for OData payloads
+ - OData Atom Format Version 4.0
+ - OData JSON Format Version 4.0
+ This specification replaces or supersedes:
+ - None
+
+Declared XML namespaces:
+ - http://docs.oasis-open.org/odata/ns/edmx
+ - http://docs.oasis-open.org/odata/ns/edm
+
+Abstract:
+ The Open Data Protocol (OData) enables the creation of REST-based data
+ services, which allow resources, identified using Uniform Resource
+ Identifiers (URLs) and defined in a data model, to be published and
+ edited by Web clients using simple HTTP messages. This document defines
+ the URL syntax for requests and the serialization format for primitive
+ literals in request and response payloads.
+
+Overview:
+ This document contains terms describing capabilities of an OData service.
+
+-->
+<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
+ <edmx:Reference Uri="http://docs.oasis-open.org/odata/odata/v4.0/os/vocabularies/Org.OData.Core.V1.xml">
+ <edmx:Include Alias="Core" Namespace="Org.OData.Core.V1" />
+ </edmx:Reference>
+ <edmx:DataServices>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Org.OData.Capabilities.V1" Alias="Capabilities">
+ <Annotation Term="Core.Description">
+ <String>
+ The Capabilities vocabulary aims to provide a way for service authors to describe
+ certain capabilities of an OData Service.
+ </String>
+ </Annotation>
+ <Annotation Term="Core.LongDescription">
+ <String>
+ There are some capabilities which are strongly recommended for services to support even
+ though they are optional. Support for $top and $skip is a good example as
+ supporting these query options helps with performance of a service and are essential. Such
+ capabilities are assumed to be default capabilities of an OData service even in
+ the case that a capabilities annotation doesn’t exist. Capabilities annotations are
+ mainly expected to be used to explicitly specify that a service doesn’t support such
+ capabilities. Capabilities annotations can as well be used to declaratively
+ specify the support of such capabilities.
+
+ On the other hand, there are some capabilities that a service may choose to support or
+ not support and in varying degrees. $filter and $orderby are such good examples.
+ This vocabulary aims to define terms to specify support or no support for such
+ capabilities.
+
+ A service is assumed to support by default the following capabilities even though an
+ annotation doesn’t exist:
+ - Countability ($count)
+ - Client pageability ($top, $skip)
+ - Expandability ($expand)
+ - Indexability by key
+ - Batch support ($batch)
+ - Navigability of navigation properties
+
+ A service is expected to support the following capabilities. If not supported, the
+ service is expected to call out the restrictions using annotations:
+ - Filterability ($filter)
+ - Sortability ($orderby)
+ - Queryability of top level entity sets
+ - Query functions
+
+ A client cannot assume that a service supports certain capabilities. A client can try, but
+ it needs to be prepared to handle an error in case the following capabilities are not
+ supported:
+ - Insertability
+ - Updatability
+ - Deletability
+ </String>
+ </Annotation>
+
+ <!-- Conformance Level -->
+
+ <Term Name="ConformanceLevel" Type="Capabilities.ConformanceLevelType" AppliesTo="EntityContainer" />
+ <EnumType Name="ConformanceLevelType">
+ <Member Name="Minimal" />
+ <Member Name="Intermediate" />
+ <Member Name="Advanced" />
+ </EnumType>
+
+ <!-- Request Capabilities -->
+
+ <Term Name="SupportedFormats" Type="Collection(Edm.String)">
+ <Annotation Term="Core.Description" String="Media types of supported formats, including format parameters" />
+ <Annotation Term="Core.IsMediaType" />
+ </Term>
+
+ <Term Name="AcceptableEncodings" Type="Collection(Edm.String)" AppliesTo="EntityContainer">
+ <Annotation Term="Core.Description" String="List of acceptable compression methods for ($batch) requests, e.g. gzip" />
+ </Term>
+
+ <!-- Supported Preferences -->
+
+ <Term Name="AsynchronousRequestsSupported" Type="Core.Tag" DefaultValue="true" AppliesTo="EntityContainer">
+ <Annotation Term="Core.Description" String="Service supports the asynchronous request preference" />
+ </Term>
+
+ <Term Name="BatchContinueOnErrorSupported" Type="Core.Tag" DefaultValue="true" AppliesTo="EntityContainer">
+ <Annotation Term="Core.Description" String="Service supports the continue on error preference" />
+ </Term>
+
+ <Term Name="IsolationSupported" Type="Capabilities.IsolationLevel" AppliesTo="EntityContainer">
+ <Annotation Term="Core.Description" String="Supported odata.isolation levels" />
+ </Term>
+ <EnumType Name="IsolationLevel" IsFlags="true">
+ <Member Name="Snapshot" Value="1" />
+ </EnumType>
+
+ <Term Name="CallbackSupported" Type="Capabilities.CallbackType" AppliesTo="EntityContainer EntitySet">
+ <Annotation Term="Core.Description" String="Supports callbacks for the specified protocols" />
+ </Term>
+ <Term Name="CrossJoinSupported" Type="Core.Tag" DefaultValue="true" AppliesTo="EntityContainer">
+ <Annotation Term="Core.Description" String="Supports cross joins for the entity sets in this container" />
+ </Term>
+ <ComplexType Name="CallbackType">
+ <Property Name="CallbackProtocols" Type="Collection(Capabilities.CallbackProtocol)" />
+ <Annotation Term="Core.Description"
+ String="A non-empty collection lists the full set of supported protocols. A empty collection means 'only HTTP is supported'" />
+ </ComplexType>
+ <ComplexType Name="CallbackProtocol">
+ <Property Name="Id" Type="Edm.String">
+ <Annotation Term="Core.Description" String="Protcol Identifier" />
+ </Property>
+ <Property Name="UrlTemplate" Type="Edm.String">
+ <Annotation Term="Core.Description"
+ String="URL Template including parameters. Parameters are enclosed in curly braces {} as defined in RFC6570" />
+ </Property>
+ <Property Name="DocumentationUrl" Type="Edm.String" Nullable="true">
+ <Annotation Term="Core.Description" String="Human readable description of the meaning of the URL Template parameters" />
+ <Annotation Term="Core.IsURL" />
+ </Property>
+ </ComplexType>
+
+ <Term Name="ChangeTracking" Type="Capabilities.ChangeTrackingType" AppliesTo="EntityContainer EntitySet">
+ <Annotation Term="Core.Description" String="Change tracking capabilities of this service or entity set" />
+ </Term>
+ <ComplexType Name="ChangeTrackingType">
+ <Property Name="Supported" Type="Edm.Boolean" DefaultValue="true">
+ <Annotation Term="Core.Description" String="This entity set supports the odata.track-changes preference" />
+ </Property>
+ <Property Name="FilterableProperties" Type="Collection(Edm.PropertyPath)">
+ <Annotation Term="Core.Description" String="Change tracking supports filters on these properties" />
+ </Property>
+ <Property Name="ExpandableProperties" Type="Collection(Edm.NavigationPropertyPath)">
+ <Annotation Term="Core.Description" String="Change tracking supports these properties expanded" />
+ </Property>
+ </ComplexType>
+
+ <!--Query Capabilities -->
+
+ <Term Name="CountRestrictions" Type="Capabilities.CountRestrictionsType" AppliesTo="EntitySet">
+ <Annotation Term="Core.Description" String="Restrictions on /$count path suffix and $count=true system query option" />
+ </Term>
+ <ComplexType Name="CountRestrictionsType">
+ <Property Name="Countable" Type="Edm.Boolean" DefaultValue="true">
+ <Annotation Term="Core.Description" String="Entities can be counted" />
+ </Property>
+ <Property Name="NonCountableProperties" Type="Collection(Edm.PropertyPath)">
+ <Annotation Term="Core.Description" String="These collection properties do not allow /$count segments" />
+ </Property>
+ <Property Name="NonCountableNavigationProperties" Type="Collection(Edm.NavigationPropertyPath)">
+ <Annotation Term="Core.Description" String="These navigation properties do not allow /$count segments" />
+ </Property>
+ </ComplexType>
+
+ <Term Name="NavigationRestrictions" Type="Capabilities.NavigationRestrictionsType" AppliesTo="EntitySet">
+ <Annotation Term="Core.Description" String="Restrictions on navigating properties according to OData URL conventions" />
+ </Term>
+ <ComplexType Name="NavigationRestrictionsType">
+ <Property Name="Navigability" Type="Capabilities.NavigationType">
+ <Annotation Term="Core.Description" String="Supported Navigability" />
+ </Property>
+ <Property Name="RestrictedProperties" Type="Collection(Capabilities.NavigationPropertyRestriction)" />
+ </ComplexType>
+ <ComplexType Name="NavigationPropertyRestriction">
+ <Property Name="NavigationProperty" Type="Edm.NavigationPropertyPath">
+ <Annotation Term="Core.Description" String="Navigation properties can be navigated" />
+ </Property>
+ <Property Name="Navigability" Type="Capabilities.NavigationType">
+ <Annotation Term="Core.Description" String="Navigation properties can be navigated to this level" />
+ </Property>
+ </ComplexType>
+ <EnumType Name="NavigationType">
+ <Member Name="Recursive">
+ <Annotation Term="Core.Description" String="Navigation properties can be recursively navigated" />
+ </Member>
+ <Member Name="Single">
+ <Annotation Term="Core.Description" String="Navigation properties can be navigated to a single level" />
+ </Member>
+ <Member Name="None">
+ <Annotation Term="Core.Description" String="Navigation properties are not navigable" />
+ </Member>
+ </EnumType>
+
+ <Term Name="IndexableByKey" Type="Core.Tag" DefaultValue="true" AppliesTo="EntitySet">
+ <Annotation Term="Core.Description" String="Supports key values according to OData URL conventions" />
+ </Term>
+
+ <Term Name="TopSupported" Type="Core.Tag" DefaultValue="true" AppliesTo="EntitySet">
+ <Annotation Term="Core.Description" String="Supports $top" />
+ </Term>
+ <Term Name="SkipSupported" Type="Core.Tag" DefaultValue="true" AppliesTo="EntitySet">
+ <Annotation Term="Core.Description" String="Supports $skip" />
+ </Term>
+
+ <Term Name="BatchSupported" Type="Core.Tag" DefaultValue="true" AppliesTo="EntityContainer">
+ <Annotation Term="Core.Description" String="Supports $batch requests" />
+ </Term>
+
+ <Term Name="FilterFunctions" Type="Collection(Edm.String)" AppliesTo="EntityContainer EntitySet">
+ <Annotation Term="Core.Description" String="List of functions supported in $filter" />
+ </Term>
+
+ <Term Name="FilterRestrictions" Type="Capabilities.FilterRestrictionsType" AppliesTo="EntitySet">
+ <Annotation Term="Core.Description" String="Restrictions on $filter expressions" />
+ </Term>
+ <ComplexType Name="FilterRestrictionsType">
+ <Property Name="Filterable" Type="Edm.Boolean" DefaultValue="true">
+ <Annotation Term="Core.Description" String="$filter is supported" />
+ </Property>
+ <Property Name="RequiresFilter" Type="Edm.Boolean" Nullable="true">
+ <Annotation Term="Core.Description" String="$filter is required" />
+ </Property>
+ <Property Name="RequiredProperties" Type="Collection(Edm.PropertyPath)">
+ <Annotation Term="Core.Description"
+ String="These properties must be specified in the $filter clause (properties of derived types are not allowed here)" />
+ </Property>
+ <Property Name="NonFilterableProperties" Type="Collection(Edm.PropertyPath)">
+ <Annotation Term="Core.Description" String="These properties cannot be used in $filter expressions" />
+ </Property>
+ </ComplexType>
+
+ <Term Name="SortRestrictions" Type="Capabilities.SortRestrictionsType" AppliesTo="EntitySet">
+ <Annotation Term="Core.Description" String="Restrictions on $orderby expressions" />
+ </Term>
+ <ComplexType Name="SortRestrictionsType">
+ <Property Name="Sortable" Type="Edm.Boolean" DefaultValue="true">
+ <Annotation Term="Core.Description" String="$orderby is supported" />
+ </Property>
+ <Property Name="AscendingOnlyProperties" Type="Collection(Edm.PropertyPath)">
+ <Annotation Term="Core.Description" String="These properties can only be used for sorting in Ascending order" />
+ </Property>
+ <Property Name="DescendingOnlyProperties" Type="Collection(Edm.PropertyPath)">
+ <Annotation Term="Core.Description" String="These properties can only be used for sorting in Descending order" />
+ </Property>
+ <Property Name="NonSortableProperties" Type="Collection(Edm.PropertyPath)">
+ <Annotation Term="Core.Description" String="These properties cannot be used in $orderby expressions" />
+ </Property>
+ </ComplexType>
+
+ <Term Name="ExpandRestrictions" Type="Capabilities.ExpandRestrictionsType" AppliesTo="EntitySet">
+ <Annotation Term="Core.Description" String="Restrictions on $expand expressions" />
+ </Term>
+ <ComplexType Name="ExpandRestrictionsType">
+ <Property Name="Expandable" Type="Edm.Boolean" DefaultValue="true">
+ <Annotation Term="Core.Description" String="$expand is supported" />
+ </Property>
+ <Property Name="NonExpandableProperties" Type="Collection(Edm.NavigationPropertyPath)">
+ <Annotation Term="Core.Description" String="These properties cannot be used in $expand expressions" />
+ </Property>
+ </ComplexType>
+
+ <Term Name="SearchRestrictions" Type="Capabilities.SearchRestrictionsType" AppliesTo="EntitySet">
+ <Annotation Term="Core.Description" String="Restrictions on $search expressions" />
+ </Term>
+ <ComplexType Name="SearchRestrictionsType">
+ <Property Name="Searchable" Type="Edm.Boolean" DefaultValue="true">
+ <Annotation Term="Core.Description" String="$search is supported" />
+ </Property>
+ <Property Name="UnsupportedExpressions" Type="Capabilities.SearchExpressions" DefaultValue="none">
+ <Annotation Term="Core.Description" String="Expressions supported in $search" />
+ </Property>
+ </ComplexType>
+ <EnumType Name="SearchExpressions" IsFlags="true">
+ <Member Name="none" Value="0" />
+ <Member Name="AND" Value="1" />
+ <Member Name="OR" Value="2" />
+ <Member Name="NOT" Value="4" />
+ <Member Name="phrase" Value="8" />
+ <Member Name="group" Value="16" />
+ </EnumType>
+
+ <!-- Data Modification Capabilities -->
+
+ <Term Name="InsertRestrictions" Type="Capabilities.InsertRestrictionsType" AppliesTo="EntitySet">
+ <Annotation Term="Core.Description" String="Restrictions on insert operations" />
+ </Term>
+ <ComplexType Name="InsertRestrictionsType">
+ <Property Name="Insertable" Type="Edm.Boolean" DefaultValue="true">
+ <Annotation Term="Core.Description" String="Entities can be inserted" />
+ </Property>
+ <Property Name="NonInsertableNavigationProperties" Type="Collection(Edm.NavigationPropertyPath)">
+ <Annotation Term="Core.Description" String="These navigation properties do not allow deep inserts" />
+ </Property>
+ </ComplexType>
+
+ <Term Name="UpdateRestrictions" Type="Capabilities.UpdateRestrictionsType" AppliesTo="EntitySet">
+ <Annotation Term="Core.Description" String="Restrictions on update operations" />
+ </Term>
+ <ComplexType Name="UpdateRestrictionsType">
+ <Property Name="Updatable" Type="Edm.Boolean" DefaultValue="true">
+ <Annotation Term="Core.Description" String="Entities can be updated" />
+ </Property>
+ <Property Name="NonUpdatableNavigationProperties" Type="Collection(Edm.NavigationPropertyPath)">
+ <Annotation Term="Core.Description" String="These navigation properties do not allow rebinding" />
+ </Property>
+ </ComplexType>
+
+ <Term Name="DeleteRestrictions" Type="Capabilities.DeleteRestrictionsType" AppliesTo="EntitySet">
+ <Annotation Term="Core.Description" String="Restrictions on delete operations" />
+ </Term>
+ <ComplexType Name="DeleteRestrictionsType">
+ <Property Name="Deletable" Type="Edm.Boolean" DefaultValue="true">
+ <Annotation Term="Core.Description" String="Entities can be deleted" />
+ </Property>
+ <Property Name="NonDeletableNavigationProperties" Type="Collection(Edm.NavigationPropertyPath)">
+ <Annotation Term="Core.Description" String="These navigation properties do not allow DeleteLink requests" />
+ </Property>
+ </ComplexType>
+
+ </Schema>
+ </edmx:DataServices>
+</edmx:Edmx>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/187c229b/lib/server-core-ext/src/main/resources/Org.OData.Core.V1.xml
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/resources/Org.OData.Core.V1.xml b/lib/server-core-ext/src/main/resources/Org.OData.Core.V1.xml
new file mode 100644
index 0000000..b9bb306
--- /dev/null
+++ b/lib/server-core-ext/src/main/resources/Org.OData.Core.V1.xml
@@ -0,0 +1,187 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+<!--
+
+ OData Version 4.0 Plus Errata 02
+ OASIS Standard incorporating Approved Errata 02
+ 30 October 2014
+ Copyright (c) OASIS Open 2014. All Rights Reserved.
+ Source: http://docs.oasis-open.org/odata/odata/v4.0/errata02/os/complete/vocabularies/
+
+-->
+<!--
+
+Technical Committee:
+ OASIS Open Data Protocol (OData) TC
+ https://www.oasis-open.org/committees/odata
+
+Chairs:
+ - Barbara Hartel (barbara.hartel@sap.com), SAP AG
+ - Ram Jeyaraman (Ram.Jeyaraman@microsoft.com), Microsoft
+
+Editors:
+ - Ralf Handl (ralf.handl@sap.com), SAP AG
+ - Michael Pizzo (mikep@microsoft.com), Microsoft
+ - Martin Zurmuehl (martin.zurmuehl@sap.com), SAP AG
+
+Additional artifacts:
+ This CSDL document is one component of a Work Product which consists of:
+ - OData Version 4.0 Part 1: Protocol
+ - OData Version 4.0 Part 2: URL Conventions
+ - OData Version 4.0 Part 3: Common Schema Definition Language (CSDL)
+ - OData ABNF Construction Rules Version 4.0
+ - OData ABNF Test Cases
+ - OData Core Vocabulary (this document)
+ - OData Capabilities Vocabulary
+ - OData Measures Vocabulary
+ - OData Metadata Service Entity Model
+ - OData EDMX XML Schema
+ - OData EDM XML Schema
+
+Related work:
+ This work product is related to the following two Work Products, each of
+ which define alternate formats for OData payloads
+ - OData Atom Format Version 4.0
+ - OData JSON Format Version 4.0
+ This specification replaces or supersedes:
+ - None
+
+Declared XML namespaces:
+ - http://docs.oasis-open.org/odata/ns/edmx
+ - http://docs.oasis-open.org/odata/ns/edm
+
+Abstract:
+ The Open Data Protocol (OData) enables the creation of REST-based data
+ services, which allow resources, identified using Uniform Resource
+ Identifiers (URLs) and defined in a data model, to be published and
+ edited by Web clients using simple HTTP messages. This document defines
+ the URL syntax for requests and the serialization format for primitive
+ literals in request and response payloads.
+
+Overview:
+ This document contains Core terms needed to write vocabularies.
+
+-->
+<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
+ <edmx:DataServices>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Org.OData.Core.V1" Alias="Core">
+ <Annotation Term="Core.Description">
+ <String>Core terms needed to write vocabularies</String>
+ </Annotation>
+
+ <!--Documentation -->
+
+ <Term Name="Description" Type="Edm.String">
+ <Annotation Term="Core.Description" String="A brief description of a model element" />
+ <Annotation Term="Core.IsLanguageDependent" />
+ </Term>
+
+ <Term Name="LongDescription" Type="Edm.String">
+ <Annotation Term="Core.Description" String="A lengthy description of a model element" />
+ <Annotation Term="Core.IsLanguageDependent" />
+ </Term>
+
+ <!-- Localization -->
+
+ <Term Name="IsLanguageDependent" Type="Core.Tag" DefaultValue="true" AppliesTo="Term Property">
+ <Annotation Term="Core.Description" String="Properties and terms annotated with this term are language-dependent" />
+ <Annotation Term="Core.RequiresType" String="Edm.String" />
+ </Term>
+
+ <!-- Term Restrictions -->
+
+ <TypeDefinition Name="Tag" UnderlyingType="Edm.Boolean">
+ <Annotation Term="Core.Description" String="This is the type to use for all tagging terms" />
+ </TypeDefinition>
+
+ <Term Name="RequiresType" Type="Edm.String" AppliesTo="Term">
+ <Annotation Term="Core.Description"
+ String="Terms annotated with this term can only be applied to elements that have a type that is identical to or derived from the given type name" />
+ </Term>
+
+ <!--Resource Paths -->
+
+ <Term Name="ResourcePath" Type="Edm.String" AppliesTo="EntitySet Singleton ActionImport FunctionImport">
+ <Annotation Term="Core.Description"
+ String="Resource path for entity container child, can be relative to xml:base and the request URL" />
+ <Annotation Term="Core.IsUrl" />
+ </Term>
+
+ <Term Name="DereferenceableIDs" Type="Core.Tag" DefaultValue="true" AppliesTo="EntityContainer">
+ <Annotation Term="Core.Description" String="Entity-ids are URLs that locate the identified entity" />
+ </Term>
+
+ <Term Name="ConventionalIDs" Type="Core.Tag" DefaultValue="true" AppliesTo="EntityContainer">
+ <Annotation Term="Core.Description" String="Entity-ids follow OData URL conventions" />
+ </Term>
+
+ <!-- Permissions -->
+
+ <Term Name="Permissions" Type="Core.Permission" AppliesTo="Property">
+ <Annotation Term="Core.Description" String="Permissions available for a property.The value of 2 is reserved for future use." />
+ </Term>
+ <EnumType Name="Permission" IsFlags="true">
+ <Member Name="None" Value="0" />
+ <Member Name="Read" Value="1" />
+ <Member Name="ReadWrite" Value="3" />
+ </EnumType>
+
+ <!-- Metadata Extensions -->
+
+ <Term Name="Immutable" Type="Core.Tag" DefaultValue="true" AppliesTo="Property">
+ <Annotation Term="Core.Description"
+ String="A value for this non-key property can be provided on insert and remains unchanged on update" />
+ </Term>
+
+ <Term Name="Computed" Type="Core.Tag" DefaultValue="true" AppliesTo="Property">
+ <Annotation Term="Core.Description" String="A value for this property is generated on both insert and update" />
+ </Term>
+
+ <Term Name="IsURL" Type="Core.Tag" DefaultValue="true" AppliesTo="Property Term">
+ <Annotation Term="Core.Description" String="Properties and terms annotated with this term MUST contain a valid URL" />
+ <Annotation Term="Core.RequiresType" String="Edm.String" />
+ </Term>
+
+ <Term Name="AcceptableMediaTypes" Type="Collection(Edm.String)" AppliesTo="EntityType Property">
+ <Annotation Term="Core.Description"
+ String="Lists the MIME types acceptable for the annotated entity type marked with HasStream="true" or the annotated stream property" />
+ <Annotation Term="Core.IsMediaType" />
+ </Term>
+
+ <Term Name="MediaType" Type="Edm.String" AppliesTo="Property">
+ <Annotation Term="Core.IsMediaType" />
+ <Annotation Term="Core.RequiresType" String="Edm.Binary" />
+ </Term>
+
+ <Term Name="IsMediaType" Type="Core.Tag" DefaultValue="true" AppliesTo="Property Term">
+ <Annotation Term="Core.Description" String="Properties and terms annotated with this term MUST contain a valid MIME type" />
+ <Annotation Term="Core.RequiresType" String="Edm.String" />
+ </Term>
+
+ <Term Name="OptimisticConcurrency" Type="Collection(Edm.PropertyPath)" AppliesTo="EntitySet">
+ <Annotation Term="Core.Description"
+ String="Data modification requires the use of Etags. A non-empty collection contains the set of properties that are used to compute the ETag" />
+ </Term>
+
+ </Schema>
+ </edmx:DataServices>
+</edmx:Edmx>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/187c229b/lib/server-core-ext/src/main/resources/Org.OData.Measures.V1.xml
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/resources/Org.OData.Measures.V1.xml b/lib/server-core-ext/src/main/resources/Org.OData.Measures.V1.xml
new file mode 100644
index 0000000..39f3e40
--- /dev/null
+++ b/lib/server-core-ext/src/main/resources/Org.OData.Measures.V1.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+<!--
+
+ OData Version 4.0 Plus Errata 02
+ OASIS Standard incorporating Approved Errata 02
+ 30 October 2014
+ Copyright (c) OASIS Open 2014. All Rights Reserved.
+ Source: http://docs.oasis-open.org/odata/odata/v4.0/errata02/os/complete/vocabularies/
+
+-->
+<!--
+
+Technical Committee:
+ OASIS Open Data Protocol (OData) TC
+ https://www.oasis-open.org/committees/odata
+
+Chairs:
+ - Barbara Hartel (barbara.hartel@sap.com), SAP AG
+ - Ram Jeyaraman (Ram.Jeyaraman@microsoft.com), Microsoft
+
+Editors:
+ - Ralf Handl (ralf.handl@sap.com), SAP AG
+ - Michael Pizzo (mikep@microsoft.com), Microsoft
+ - Martin Zurmuehl (martin.zurmuehl@sap.com), SAP AG
+
+Additional artifacts:
+ This CSDL document is one component of a Work Product which consists of:
+ - OData Version 4.0 Part 1: Protocol
+ - OData Version 4.0 Part 2: URL Conventions
+ - OData Version 4.0 Part 3: Common Schema Definition Language (CSDL)
+ - OData ABNF Construction Rules Version 4.0
+ - OData ABNF Test Cases
+ - OData Core Vocabulary
+ - OData Capabilities Vocabulary
+ - OData Measures Vocabulary (this document)
+ - OData Metadata Service Entity Model
+ - OData EDMX XML Schema
+ - OData EDM XML Schema
+
+Related work:
+ This work product is related to the following two Work Products, each of
+ which define alternate formats for OData payloads
+ - OData Atom Format Version 4.0
+ - OData JSON Format Version 4.0
+ This specification replaces or supersedes:
+ - None
+
+Declared XML namespaces:
+ - http://docs.oasis-open.org/odata/ns/edmx
+ - http://docs.oasis-open.org/odata/ns/edm
+
+Abstract:
+ The Open Data Protocol (OData) enables the creation of REST-based data
+ services, which allow resources, identified using Uniform Resource
+ Identifiers (URLs) and defined in a data model, to be published and
+ edited by Web clients using simple HTTP messages. This document defines
+ the URL syntax for requests and the serialization format for primitive
+ literals in request and response payloads.
+
+Overview:
+ This document contains terms describing monetary amounts and measured quantities.
+
+-->
+<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
+ <edmx:Reference Uri="http://docs.oasis-open.org/odata/odata/v4.0/os/vocabularies/Org.OData.Core.V1.xml">
+ <edmx:Include Alias="Core" Namespace="Org.OData.Core.V1" />
+ </edmx:Reference>
+ <edmx:DataServices>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Org.OData.Measures.V1" Alias="Measures">
+ <Annotation Term="Core.Description">
+ <String>Terms describing monetary amounts and measured quantities</String>
+ </Annotation>
+
+ <Term Name="ISOCurrency" Type="Edm.String" AppliesTo="Property">
+ <Annotation Term="Core.Description" String="The currency for this monetary amount as an ISO 4217 currency code" />
+ </Term>
+
+ <Term Name="Scale" Type="Edm.Byte" AppliesTo="Property">
+ <Annotation Term="Core.Description"
+ String="The number of significant decimal places in the scale part (less than or equal to the number declared in the Scale facet)" />
+ <Annotation Term="Core.RequiresType" String="Edm.Decimal" />
+ </Term>
+
+ <Term Name="Unit" Type="Edm.String" AppliesTo="Property">
+ <Annotation Term="Core.Description" String="The unit of measure for this measured quantity, e.g. cm for centimeters or % for percentages" />
+ </Term>
+
+ </Schema>
+ </edmx:DataServices>
+</edmx:Edmx>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/187c229b/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserAnnotationsTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserAnnotationsTest.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserAnnotationsTest.java
index 7912dc8..d71c54d 100644
--- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserAnnotationsTest.java
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserAnnotationsTest.java
@@ -51,7 +51,7 @@ import org.junit.Before;
import org.junit.Test;
public class MetadataParserAnnotationsTest {
- final String NS = "Org.OData.Core.V1";
+ final String NS = "Org.OData.AnnoatationTest";
final FullQualifiedName NSF = new FullQualifiedName(NS);
CsdlEdmProvider provider = null;
@@ -59,7 +59,8 @@ public class MetadataParserAnnotationsTest {
@Before
public void setUp() throws Exception {
MetadataParser parser = new MetadataParser();
- parser.setParseAnnotations(true);
+ parser.parseAnnotations(true);
+ parser.loadCoreVocabularies(true);
provider = (CsdlEdmProvider) parser.buildEdmProvider(new FileReader("src/test/resources/annotations.xml"));
}
@@ -204,5 +205,11 @@ public class MetadataParserAnnotationsTest {
public void testTermAppliesTo() throws ODataException {
CsdlTerm term = this.provider.getTerm(new FullQualifiedName(NS, "IsURI"));
assertEquals(Arrays.asList("Property", "PropertyPath"), term.getAppliesTo());
+ }
+
+ @Test
+ public void checkCoreVocabularies() throws ODataException {
+ CsdlTerm term = this.provider.getTerm(new FullQualifiedName("Org.OData.Core.V1", "Description"));
+ assertEquals("Edm.String", term.getType());
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/187c229b/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserTest.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserTest.java
index 97f19b5..83160b4 100644
--- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserTest.java
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserTest.java
@@ -54,7 +54,7 @@ public class MetadataParserTest {
@Before
public void setUp() throws Exception {
MetadataParser parser = new MetadataParser();
- parser.setParseAnnotations(true);
+ parser.parseAnnotations(true);
provider = (CsdlEdmProvider) parser.buildEdmProvider(new FileReader("src/test/resources/trippin.xml"));
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/187c229b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServlet.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServlet.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServlet.java
index 036cd78..06e498c 100644
--- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServlet.java
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServlet.java
@@ -50,6 +50,8 @@ public class TripPinServlet extends HttpServlet {
ServiceMetadata metadata = null;
try {
+ parser.parseAnnotations(true);
+ parser.loadCoreVocabularies(true);
metadata = parser.buildServiceMetadata(new FileReader("src/test/resources/trippin.xml"));
} catch (XMLStreamException e) {
throw new IOException(e);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/187c229b/lib/server-core-ext/src/test/resources/annotations.xml
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/resources/annotations.xml b/lib/server-core-ext/src/test/resources/annotations.xml
index fce46a8..1c5281a 100644
--- a/lib/server-core-ext/src/test/resources/annotations.xml
+++ b/lib/server-core-ext/src/test/resources/annotations.xml
@@ -13,7 +13,7 @@
Version="4.0">
<edmx:DataServices>
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm"
- Namespace="Org.OData.Core.V1" Alias="Core">
+ Namespace="Org.OData.AnnoatationTest" Alias="test">
<Annotation Term="Core.Description">
<String>Core terms needed to write vocabularies</String>
[08/22] olingo-odata4 git commit: [OLINGO-852] less warnings +
general clean-up
Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/Services.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/Services.java b/fit/src/main/java/org/apache/olingo/fit/Services.java
index 45f11a5..698938e 100644
--- a/fit/src/main/java/org/apache/olingo/fit/Services.java
+++ b/fit/src/main/java/org/apache/olingo/fit/Services.java
@@ -25,15 +25,22 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.URI;
+import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.ConcurrentModificationException;
+import java.util.Enumeration;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.UUID;
+import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import javax.mail.Header;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;
import javax.ws.rs.BadRequestException;
@@ -51,6 +58,8 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.UriInfo;
@@ -59,63 +68,140 @@ import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
+import org.apache.commons.lang3.tuple.Pair;
import org.apache.cxf.interceptor.InInterceptors;
+import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import org.apache.cxf.jaxrs.ext.multipart.Multipart;
import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
import org.apache.olingo.client.api.data.ResWrap;
+import org.apache.olingo.client.api.serialization.ODataDeserializer;
+import org.apache.olingo.client.api.serialization.ODataSerializer;
+import org.apache.olingo.client.core.serialization.AtomSerializer;
+import org.apache.olingo.client.core.serialization.JsonDeserializer;
+import org.apache.olingo.client.core.serialization.JsonSerializer;
+import org.apache.olingo.commons.api.data.ComplexValue;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.data.Link;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.data.ValueType;
-import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.core.edm.EdmTypeInfo;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
+import org.apache.olingo.fit.metadata.EntityType;
import org.apache.olingo.fit.metadata.Metadata;
+import org.apache.olingo.fit.metadata.NavigationProperty;
import org.apache.olingo.fit.methods.PATCH;
import org.apache.olingo.fit.rest.ResolvingReferencesInterceptor;
import org.apache.olingo.fit.rest.XHTTPMethodInterceptor;
+import org.apache.olingo.fit.serializer.FITAtomDeserializer;
import org.apache.olingo.fit.utils.AbstractUtilities;
import org.apache.olingo.fit.utils.Accept;
import org.apache.olingo.fit.utils.Commons;
import org.apache.olingo.fit.utils.ConstantKey;
import org.apache.olingo.fit.utils.Constants;
import org.apache.olingo.fit.utils.FSManager;
+import org.apache.olingo.fit.utils.JSONUtilities;
import org.apache.olingo.fit.utils.LinkInfo;
+import org.apache.olingo.fit.utils.XMLUtilities;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
@Service
@Path("/V40/Static.svc")
@InInterceptors(classes = { XHTTPMethodInterceptor.class, ResolvingReferencesInterceptor.class })
-public class Services extends AbstractServices {
+public class Services {
/**
- * CR/LF.
+ * Logger.
*/
- protected static final byte[] CRLF = { 13, 10 };
-
- protected static final Pattern RELENTITY_SELECT_PATTERN = Pattern.compile("^.*\\(\\$select=.*\\)$");
+ protected static final Logger LOG = LoggerFactory.getLogger(Services.class);
- protected static final Pattern CROSSJOIN_PATTERN = Pattern.compile(
+ private static final Pattern REQUEST_PATTERN = Pattern.compile("(.*) (http://.*) HTTP/.*");
+ private static final Pattern BATCH_REQUEST_REF_PATTERN = Pattern.compile("(.*) ([$]\\d+)(.*) HTTP/.*");
+ private static final Pattern REF_PATTERN = Pattern.compile("([$]\\d+)");
+ private static final Pattern RELENTITY_SELECT_PATTERN = Pattern.compile("^.*\\(\\$select=.*\\)$");
+ private static final Pattern CROSSJOIN_PATTERN = Pattern.compile(
"^\\$crossjoin\\(.*\\)\\?\\$filter=\\([a-zA-Z/]+ eq [a-zA-Z/]+\\)$");
+ protected static final String BOUNDARY = "batch_243234_25424_ef_892u748";
+ protected static final String MULTIPART_MIXED = "multipart/mixed";
+ protected static final String APPLICATION_OCTET_STREAM = "application/octet-stream";
private final Map<String, String> providedAsync = new HashMap<String, String>();
+ protected final ODataDeserializer atomDeserializer = new FITAtomDeserializer();
+ protected final ODataDeserializer jsonDeserializer = new JsonDeserializer(true);
+ protected final ODataSerializer atomSerializer = new AtomSerializer(true);
+ protected final ODataSerializer jsonSerializer = new JsonSerializer(true, ContentType.JSON_FULL_METADATA);
+
+ protected final Metadata metadata;
+ protected final XMLUtilities xml;
+ protected final JSONUtilities json;
+
public Services() throws IOException {
- super(ODataServiceVersion.V40, Commons.getMetadata(ODataServiceVersion.V40));
+ this(Commons.getMetadata());
}
protected Services(final Metadata metadata) throws IOException {
- super(ODataServiceVersion.V40, metadata);
+ this.metadata = metadata;
+ xml = new XMLUtilities(metadata);
+ json = new JSONUtilities(metadata);
+ }
+
+ /**
+ * Provide sample services.
+ *
+ * @param accept Accept header.
+ * @return OData services.
+ */
+ @GET
+ public Response getServices(@HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept) {
+ try {
+ final Accept acceptType = Accept.parse(accept);
+
+ if (acceptType == Accept.ATOM) {
+ throw new UnsupportedMediaTypeException("Unsupported media type");
+ }
+
+ return xml.createResponse(
+ null,
+ FSManager.instance().readFile(Constants.get(ConstantKey.SERVICES), acceptType),
+ null, acceptType);
+ } catch (Exception e) {
+ return xml.createFaultResponse(accept, e);
+ }
+ }
+
+ /**
+ * Provide sample getMetadata().
+ *
+ * @return getMetadata().
+ */
+ @GET
+ @Path("/$metadata")
+ @Produces(MediaType.APPLICATION_XML)
+ public Response getMetadata() {
+ return getMetadata(Constants.get(ConstantKey.METADATA));
+ }
+
+ protected Response getMetadata(final String filename) {
+ try {
+ return xml.createResponse(null, FSManager.instance().readRes(filename, Accept.XML), null, Accept.XML);
+ } catch (Exception e) {
+ return xml.createFaultResponse(Accept.XML.toString(), e);
+ }
}
@GET
@Path("/redirect/{name}({id})")
- public Response conformanceRedirect(
- @Context final UriInfo uriInfo,
- @PathParam("name") final String name,
- @PathParam("id") final String id) {
+ public Response conformanceRedirect(@Context final UriInfo uriInfo) {
return Response.temporaryRedirect(
URI.create(uriInfo.getRequestUri().toASCIIString().replace("/redirect", ""))).build();
}
@@ -128,7 +214,7 @@ public class Services extends AbstractServices {
try {
if (CROSSJOIN_PATTERN.matcher("$crossjoin(" + elements + ")?$filter=" + filter).matches()) {
- final InputStream feed = FSManager.instance(version).readFile("crossjoin", Accept.JSON);
+ final InputStream feed = FSManager.instance().readFile("crossjoin", Accept.JSON);
return xml.createResponse(feed, null, Accept.JSON_FULLMETA);
} else {
@@ -141,9 +227,7 @@ public class Services extends AbstractServices {
@GET
@Path("/relatedEntitySelect/{path:.*}")
- public Response relatedEntitySelect(
- @PathParam("path") final String path,
- @QueryParam("$expand") final String expand) {
+ public Response relatedEntitySelect(@QueryParam("$expand") final String expand) {
if (RELENTITY_SELECT_PATTERN.matcher(expand).matches()) {
return xml.createResponse(null, null, Accept.JSON_FULLMETA);
@@ -177,7 +261,6 @@ public class Services extends AbstractServices {
@PUT
@Path("/People(1)/Parent")
public Response changeSingleValuedNavigationPropertyReference(
- @Context final UriInfo uriInfo,
@HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
@HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
final String content) {
@@ -196,39 +279,95 @@ public class Services extends AbstractServices {
}
@POST
- @Path("/async/$batch")
- public Response async(
- @Context final UriInfo uriInfo,
+ @Path("/$batch")
+ @Consumes(MULTIPART_MIXED)
+ @Produces(APPLICATION_OCTET_STREAM + ";boundary=" + BOUNDARY)
+ public Response batch(
@HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
final @Multipart MultipartBody attachment) {
+ try {
+ final boolean continueOnError = prefer.contains("odata.continue-on-error");
+ return xml.createBatchResponse(
+ exploreMultipart(attachment.getAllAttachments(), BOUNDARY, continueOnError));
+ } catch (IOException e) {
+ return xml.createFaultResponse(Accept.XML.toString(), e);
+ }
+ }
+
+ // ----------------------------------------------
+ // just for non nullable property test into PropertyTestITCase
+ // ----------------------------------------------
+ @PATCH
+ @Path("/Driver('2')")
+ public Response patchDriver() {
+ return xml.createFaultResponse(Accept.JSON_FULLMETA.toString(), new Exception("Non nullable properties"));
+ }
+
+ @GET
+ @Path("/StoredPIs(1000)")
+ public Response getStoredPI(@Context final UriInfo uriInfo) {
+ final Entity entity = new Entity();
+ entity.setType("Microsoft.Test.OData.Services.ODataWCFService.StoredPI");
+ final Property id = new Property();
+ id.setType("Edm.Int32");
+ id.setName("StoredPIID");
+ id.setValue(ValueType.PRIMITIVE, 1000);
+ entity.getProperties().add(id);
+ final Link edit = new Link();
+ edit.setHref(uriInfo.getRequestUri().toASCIIString());
+ edit.setRel("edit");
+ edit.setTitle("StoredPI");
+ entity.setEditLink(edit);
+
+ final ByteArrayOutputStream content = new ByteArrayOutputStream();
+ final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING);
+ try {
+ jsonSerializer.write(writer, new ResWrap<Entity>((URI) null, null, entity));
+ return xml.createResponse(new ByteArrayInputStream(content.toByteArray()), null, Accept.JSON_FULLMETA);
+ } catch (Exception e) {
+ LOG.error("While creating StoredPI", e);
+ return xml.createFaultResponse(Accept.JSON_FULLMETA.toString(), e);
+ }
+ }
+
+ @PATCH
+ @Path("/StoredPIs(1000)")
+ public Response patchStoredPI() {
+ // just for non nullable property test into PropertyTestITCase
+ return xml.createFaultResponse(Accept.JSON_FULLMETA.toString(), new Exception("Non nullable properties"));
+ }
+
+ @POST
+ @Path("/async/$batch")
+ public Response async(@Context final UriInfo uriInfo) {
try {
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write("HTTP/1.1 200 Ok".getBytes());
- bos.write(CRLF);
+ bos.write(Constants.CRLF);
bos.write("OData-Version: 4.0".getBytes());
- bos.write(CRLF);
+ bos.write(Constants.CRLF);
bos.write(("Content-Type: " + ContentType.APPLICATION_OCTET_STREAM + ";boundary=" + BOUNDARY).getBytes());
- bos.write(CRLF);
- bos.write(CRLF);
+ bos.write(Constants.CRLF);
+ bos.write(Constants.CRLF);
bos.write(("--" + BOUNDARY).getBytes());
- bos.write(CRLF);
+ bos.write(Constants.CRLF);
bos.write("Content-Type: application/http".getBytes());
- bos.write(CRLF);
+ bos.write(Constants.CRLF);
bos.write("Content-Transfer-Encoding: binary".getBytes());
- bos.write(CRLF);
- bos.write(CRLF);
+ bos.write(Constants.CRLF);
+ bos.write(Constants.CRLF);
bos.write("HTTP/1.1 202 Accepted".getBytes());
- bos.write(CRLF);
+ bos.write(Constants.CRLF);
bos.write("Location: http://service-root/async-monitor".getBytes());
- bos.write(CRLF);
+ bos.write(Constants.CRLF);
bos.write("Retry-After: 10".getBytes());
- bos.write(CRLF);
- bos.write(CRLF);
+ bos.write(Constants.CRLF);
+ bos.write(Constants.CRLF);
bos.write(("--" + BOUNDARY + "--").getBytes());
- bos.write(CRLF);
+ bos.write(Constants.CRLF);
final UUID uuid = UUID.randomUUID();
providedAsync.put(uuid.toString(), bos.toString(Constants.ENCODING.toString()));
@@ -263,11 +402,13 @@ public class Services extends AbstractServices {
? Constants.get(ConstantKey.ENTITY)
: Constants.get(ConstantKey.FEED));
- final InputStream feed = FSManager.instance(version).readFile(path.toString(), acceptType);
+ final InputStream feed = FSManager.instance().readFile(path.toString(), acceptType);
final StringBuilder builder = new StringBuilder();
- builder.append("HTTP/1.1 200 Ok").append(new String(CRLF));
- builder.append("Content-Type: ").append(accept).append(new String(CRLF)).append(new String(CRLF));
+ builder.append("HTTP/1.1 200 Ok").append(new String(Constants.CRLF));
+ builder.append("Content-Type: ").append(accept)
+ .append(new String(Constants.CRLF))
+ .append(new String(Constants.CRLF));
builder.append(IOUtils.toString(feed));
IOUtils.closeQuietly(feed);
@@ -281,15 +422,80 @@ public class Services extends AbstractServices {
}
}
- @Override
- protected void setInlineCount(final EntityCollection entitySet, final String count) {
+ private void setInlineCount(final EntityCollection entitySet, final String count) {
if ("true".equals(count)) {
entitySet.setCount(entitySet.getEntities().size());
}
}
- @Override
- public InputStream exploreMultipart(
+ private Response bodyPartRequest(final MimeBodyPart body, final Map<String, String> references) throws Exception {
+ @SuppressWarnings("unchecked")
+ final Enumeration<Header> en = body.getAllHeaders();
+
+ Header header = en.nextElement();
+ final String request =
+ header.getName() + (StringUtils.isNotBlank(header.getValue()) ? ":" + header.getValue() : "");
+
+ final Matcher matcher = REQUEST_PATTERN.matcher(request);
+ final Matcher matcherRef = BATCH_REQUEST_REF_PATTERN.matcher(request);
+
+ final MultivaluedMap<String, String> headers = new MultivaluedHashMap<String, String>();
+
+ while (en.hasMoreElements()) {
+ header = en.nextElement();
+ headers.putSingle(header.getName(), header.getValue());
+ }
+
+ final Response res;
+ final String url;
+ final String method;
+
+ if (matcher.find()) {
+ url = matcher.group(2);
+ method = matcher.group(1);
+ } else if (matcherRef.find()) {
+ url = references.get(matcherRef.group(2)) + matcherRef.group(3);
+ method = matcherRef.group(1);
+ } else {
+ url = null;
+ method = null;
+ }
+
+ if (url == null) {
+ res = null;
+ } else {
+ final WebClient client = WebClient.create(url, "odatajclient", "odatajclient", null);
+ client.headers(headers);
+
+ if ("DELETE".equals(method)) {
+ res = client.delete();
+ } else {
+ final InputStream is = body.getDataHandler().getInputStream();
+ String content = IOUtils.toString(is);
+ IOUtils.closeQuietly(is);
+
+ final Matcher refs = REF_PATTERN.matcher(content);
+
+ while (refs.find()) {
+ content = content.replace(refs.group(1), references.get(refs.group(1)));
+ }
+
+ if ("PATCH".equals(method) || "MERGE".equals(method)) {
+ client.header("X-HTTP-METHOD", method);
+ res = client.invoke("POST", IOUtils.toInputStream(content));
+ } else {
+ res = client.invoke(method, IOUtils.toInputStream(content));
+ }
+ }
+
+ // When updating to CXF 3.0.1, uncomment the following line, see CXF-5865
+ // client.close();
+ }
+
+ return res;
+ }
+
+ private InputStream exploreMultipart(
final List<Attachment> attachments, final String boundary, final boolean continueOnError)
throws IOException {
@@ -349,9 +555,10 @@ public class Services extends AbstractServices {
goon = continueOnError;
}
} else {
- addItemIntro(bos);
+ addItemIntro(bos, null);
- res = bodyPartRequest(new MimeBodyPart(obj.getDataHandler().getInputStream()));
+ res = bodyPartRequest(new MimeBodyPart(obj.getDataHandler().getInputStream()),
+ Collections.<String, String> emptyMap());
if (res.getStatus() >= 400) {
goon = continueOnError;
@@ -374,121 +581,131 @@ public class Services extends AbstractServices {
return new ByteArrayInputStream(bos.toByteArray());
}
- @GET
- @Path("/People/{type:.*}")
- public Response getPeople(
- @Context final UriInfo uriInfo,
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @PathParam("type") final String type,
- @QueryParam("$top") @DefaultValue(StringUtils.EMPTY) final String top,
- @QueryParam("$skip") @DefaultValue(StringUtils.EMPTY) final String skip,
- @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
- @QueryParam("$count") @DefaultValue(StringUtils.EMPTY) final String count,
- @QueryParam("$filter") @DefaultValue(StringUtils.EMPTY) final String filter,
- @QueryParam("$search") @DefaultValue(StringUtils.EMPTY) final String search,
- @QueryParam("$orderby") @DefaultValue(StringUtils.EMPTY) final String orderby,
- @QueryParam("$skiptoken") @DefaultValue(StringUtils.EMPTY) final String skiptoken) {
+ private void addItemIntro(final ByteArrayOutputStream bos, final String contentId) throws IOException {
+ bos.write("Content-Type: application/http".getBytes());
+ bos.write(Constants.CRLF);
+ bos.write("Content-Transfer-Encoding: binary".getBytes());
+ bos.write(Constants.CRLF);
- return StringUtils.isBlank(filter) && StringUtils.isBlank(search)
- ? NumberUtils.isNumber(type)
- ? super.getEntityInternal(
- uriInfo.getRequestUri().toASCIIString(), accept, "People", type, format, null, null)
- : super.getEntitySet(accept, "People", type)
- : super.getEntitySet(uriInfo, accept, "People", top, skip, format, count, filter, orderby, skiptoken, type);
+ if (StringUtils.isNotBlank(contentId)) {
+ bos.write(("Content-ID: " + contentId).getBytes());
+ bos.write(Constants.CRLF);
+ }
+
+ bos.write(Constants.CRLF);
}
- @GET
- @Path("/Boss")
- public Response getSingletonBoss(
- @Context final UriInfo uriInfo,
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+ private void addChangesetItemIntro(
+ final ByteArrayOutputStream bos, final String contentId, final String cboundary) throws IOException {
+ bos.write(("--" + cboundary).getBytes());
+ bos.write(Constants.CRLF);
+ bos.write(("Content-ID: " + contentId).getBytes());
+ bos.write(Constants.CRLF);
+ addItemIntro(bos, null);
+ }
- return getEntityInternal(
- uriInfo.getRequestUri().toASCIIString(), accept, "Boss", StringUtils.EMPTY, format, null, null);
+ private void addSingleBatchResponse(
+ final Response response, final ByteArrayOutputStream bos) throws IOException {
+ addSingleBatchResponse(response, null, bos);
}
- @GET
- @Path("/Company")
- public Response getSingletonCompany(
- @Context final UriInfo uriInfo,
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+ private void addSingleBatchResponse(
+ final Response response, final String contentId, final ByteArrayOutputStream bos) throws IOException {
+ bos.write("HTTP/1.1 ".getBytes());
+ bos.write(String.valueOf(response.getStatusInfo().getStatusCode()).getBytes());
+ bos.write(" ".getBytes());
+ bos.write(response.getStatusInfo().getReasonPhrase().getBytes());
+ bos.write(Constants.CRLF);
- return getEntityInternal(
- uriInfo.getRequestUri().toASCIIString(), accept, "Company", StringUtils.EMPTY, format, null, null);
+ for (Map.Entry<String, List<Object>> header : response.getHeaders().entrySet()) {
+ final StringBuilder builder = new StringBuilder();
+ for (Object value : header.getValue()) {
+ if (builder.length() > 0) {
+ builder.append(", ");
+ }
+ builder.append(value.toString());
+ }
+ builder.insert(0, ": ").insert(0, header.getKey());
+ bos.write(builder.toString().getBytes());
+ bos.write(Constants.CRLF);
+ }
+
+ if (StringUtils.isNotBlank(contentId)) {
+ bos.write(("Content-ID: " + contentId).getBytes());
+ bos.write(Constants.CRLF);
+ }
+
+ bos.write(Constants.CRLF);
+
+ final Object entity = response.getEntity();
+ if (entity != null) {
+ bos.write(IOUtils.toByteArray((InputStream) entity));
+ bos.write(Constants.CRLF);
+ }
+
+ bos.write(Constants.CRLF);
}
- @PATCH
- @Path("/Company")
- @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
- @Consumes({ MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
- public Response patchSingletonCompany(
- @Context final UriInfo uriInfo,
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
- @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
- @HeaderParam("If-Match") @DefaultValue(StringUtils.EMPTY) final String ifMatch,
- final String changes) {
+ protected void addErrorBatchResponse(final Exception e, final ByteArrayOutputStream bos)
+ throws IOException {
+ addErrorBatchResponse(e, null, bos);
+ }
- return super.patchEntity(uriInfo, accept, contentType, prefer, ifMatch, "Company", StringUtils.EMPTY, changes);
+ protected void addErrorBatchResponse(final Exception e, final String contentId, final ByteArrayOutputStream bos)
+ throws IOException {
+ addSingleBatchResponse(xml.createFaultResponse(Accept.XML.toString(), e), contentId, bos);
}
+ /**
+ * Retrieve entities from the given entity set and the given type.
+ *
+ * @param accept Accept header.
+ * @param name entity set.
+ * @param type entity type.
+ * @return entity set.
+ */
@GET
- @Path("/Customers")
- public Response getCustomers(
- @Context final UriInfo uriInfo,
+ @Path("/{name}/{type:[a-zA-Z].*}")
+ public Response getEntitySet(
@HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
- @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
- @QueryParam("$deltatoken") @DefaultValue(StringUtils.EMPTY) final String deltatoken) {
+ @PathParam("name") final String name,
+ @PathParam("type") final String type) {
try {
- final Accept acceptType;
- if (StringUtils.isNotBlank(format)) {
- acceptType = Accept.valueOf(format.toUpperCase());
- } else {
- acceptType = Accept.parse(accept);
+ final Accept acceptType = Accept.parse(accept);
+ if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
+ throw new UnsupportedMediaTypeException("Unsupported media type");
}
- final InputStream output;
- if (StringUtils.isBlank(deltatoken)) {
- final InputStream input = (InputStream) getEntitySet(
- uriInfo, accept, "Customers", null, null, format, null, null, null, null).getEntity();
- final EntityCollection entitySet = xml.readEntitySet(acceptType, input);
-
- boolean trackChanges = prefer.contains("odata.track-changes");
- if (trackChanges) {
- entitySet.setDeltaLink(URI.create("Customers?$deltatoken=8015"));
- }
+ final String basePath = name + File.separatorChar;
+ final StringBuilder path = new StringBuilder(name).
+ append(File.separatorChar).append(type).
+ append(File.separatorChar);
- output = xml.writeEntitySet(acceptType, new ResWrap<EntityCollection>(
- URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX) + "Customers"),
- null,
- entitySet));
- } else {
- output = FSManager.instance(version).readFile("delta", acceptType);
- }
+ path.append(metadata.getEntitySet(name).isSingleton()
+ ? Constants.get(ConstantKey.ENTITY)
+ : Constants.get(ConstantKey.FEED));
- final Response response = xml.createResponse(
- null,
- output,
- null,
- acceptType);
- if (StringUtils.isNotBlank(prefer)) {
- response.getHeaders().put("Preference-Applied", Collections.<Object> singletonList(prefer));
- }
- return response;
+ final InputStream feed = FSManager.instance().readFile(path.toString(), acceptType);
+ return xml.createResponse(null, feed, Commons.getETag(basePath), acceptType);
} catch (Exception e) {
return xml.createFaultResponse(accept, e);
}
}
@GET
- @Path("/Company/Microsoft.Test.OData.Services.ODataWCFService.GetEmployeesCount{paren:[\\(\\)]*}")
- public Response functionGetEmployeesCount(
+ @Path("/{name}/{type:[a-zA-Z].*}")
+ public Response getEntitySet(@Context final UriInfo uriInfo,
@HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+ @PathParam("name") final String name,
+ @QueryParam("$top") @DefaultValue(StringUtils.EMPTY) final String top,
+ @QueryParam("$skip") @DefaultValue(StringUtils.EMPTY) final String skip,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
+ @QueryParam("$count") @DefaultValue(StringUtils.EMPTY) final String count,
+ @QueryParam("$filter") @DefaultValue(StringUtils.EMPTY) final String filter,
+ @QueryParam("$orderby") @DefaultValue(StringUtils.EMPTY) final String orderby,
+ @QueryParam("$skiptoken") @DefaultValue(StringUtils.EMPTY) final String skiptoken,
+ @PathParam("type") final String type) {
try {
final Accept acceptType;
@@ -498,111 +715,450 @@ public class Services extends AbstractServices {
acceptType = Accept.parse(accept);
}
- final Property property = new Property();
- property.setType("Edm.Int32");
- property.setValue(ValueType.PRIMITIVE, 2);
- final ResWrap<Property> container = new ResWrap<Property>(
- URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX) + property.getType()), null,
- property);
+ final String location = uriInfo.getRequestUri().toASCIIString();
+ try {
+ // search for function ...
+ final InputStream func = FSManager.instance().readFile(name, acceptType);
+ return xml.createResponse(location, func, null, acceptType);
+ } catch (NotFoundException e) {
+ if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
+ throw new UnsupportedMediaTypeException("Unsupported media type");
+ }
- return xml.createResponse(
- null,
- xml.writeProperty(acceptType, container),
- null,
- acceptType);
- } catch (Exception e) {
- return xml.createFaultResponse(accept, e);
- }
- }
+ // search for entitySet ...
+ final String basePath = name + File.separatorChar;
- @POST
- @Path("/Company/Microsoft.Test.OData.Services.ODataWCFService.IncreaseRevenue{paren:[\\(\\)]*}")
- public Response actionIncreaseRevenue(
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
- @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
- final String param) {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(basePath);
- try {
- final Accept acceptType;
- if (StringUtils.isNotBlank(format)) {
- acceptType = Accept.valueOf(format.toUpperCase());
- } else {
- acceptType = Accept.parse(accept);
- }
+ if (type != null) {
+ builder.append(type).append(File.separatorChar);
+ }
- final Accept contentTypeValue = Accept.parse(contentType);
- final Entity entry = xml.readEntity(contentTypeValue, IOUtils.toInputStream(param, Constants.ENCODING));
+ if (StringUtils.isNotBlank(orderby)) {
+ builder.append(Constants.get(ConstantKey.ORDERBY)).append(File.separatorChar).
+ append(orderby).append(File.separatorChar);
+ }
- return xml.createResponse(
- null,
- xml.writeProperty(acceptType, entry.getProperty("IncreaseValue")),
- null,
- acceptType);
+ if (StringUtils.isNotBlank(filter)) {
+ builder.append(Constants.get(ConstantKey.FILTER)).append(File.separatorChar).
+ append(filter.replaceAll("/", "."));
+ } else if (StringUtils.isNotBlank(skiptoken)) {
+ builder.append(Constants.get(ConstantKey.SKIP_TOKEN)).append(File.separatorChar).
+ append(skiptoken);
+ } else {
+ builder.append(metadata.getEntitySet(name).isSingleton()
+ ? Constants.get(ConstantKey.ENTITY)
+ : Constants.get(ConstantKey.FEED));
+ }
+
+ final InputStream feed = FSManager.instance().readFile(builder.toString(), Accept.ATOM);
+
+ final ResWrap<EntityCollection> container = atomDeserializer.toEntitySet(feed);
+
+ setInlineCount(container.getPayload(), count);
+
+ final ByteArrayOutputStream content = new ByteArrayOutputStream();
+ final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING);
+
+ // -----------------------------------------------
+ // Evaluate $skip and $top
+ // -----------------------------------------------
+ List<Entity> entries = new ArrayList<Entity>(container.getPayload().getEntities());
+
+ if (StringUtils.isNotBlank(skip)) {
+ entries = entries.subList(Integer.valueOf(skip), entries.size());
+ }
+
+ if (StringUtils.isNotBlank(top)) {
+ entries = entries.subList(0, Integer.valueOf(top));
+ }
+
+ container.getPayload().getEntities().clear();
+ container.getPayload().getEntities().addAll(entries);
+ // -----------------------------------------------
+
+ if (acceptType == Accept.ATOM) {
+ atomSerializer.write(writer, container);
+ } else {
+ jsonSerializer.write(writer, container);
+ }
+ writer.flush();
+ writer.close();
+
+ return xml.createResponse(
+ location,
+ new ByteArrayInputStream(content.toByteArray()),
+ Commons.getETag(basePath),
+ acceptType);
+ }
} catch (Exception e) {
return xml.createFaultResponse(accept, e);
}
}
+ /**
+ * Retrieve entity set or function execution sample.
+ *
+ * @param accept Accept header.
+ * @param name entity set or function name.
+ * @param format format query option.
+ * @param count count query option.
+ * @param filter filter query option.
+ * @param orderby orderby query option.
+ * @param skiptoken skiptoken query option.
+ * @return entity set or function result.
+ */
@GET
- @Path("/Products({entityId})/Microsoft.Test.OData.Services.ODataWCFService.GetProductDetails({param:.*})")
- public Response functionGetProductDetails(
+ @Path("/{name}")
+ public Response getEntitySet(
+ @Context final UriInfo uriInfo,
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @PathParam("name") final String name,
+ @QueryParam("$top") @DefaultValue(StringUtils.EMPTY) final String top,
+ @QueryParam("$skip") @DefaultValue(StringUtils.EMPTY) final String skip,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
+ @QueryParam("$count") @DefaultValue(StringUtils.EMPTY) final String count,
+ @QueryParam("$filter") @DefaultValue(StringUtils.EMPTY) final String filter,
+ @QueryParam("$orderby") @DefaultValue(StringUtils.EMPTY) final String orderby,
+ @QueryParam("$skiptoken") @DefaultValue(StringUtils.EMPTY) final String skiptoken) {
+
+ return getEntitySet(uriInfo, accept, name, top, skip, format, count, filter, orderby, skiptoken, null);
+ }
+
+ @GET
+ @Path("/Person({entityId})")
+ public Response getPerson(
+ @Context final UriInfo uriInfo,
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @PathParam("entityId") final String entityId,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+ final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
+
+ final Response internal = getEntityInternal(
+ uriInfo.getRequestUri().toASCIIString(), accept, "Person", entityId, format, null, null);
+ if (internal.getStatus() == 200) {
+ InputStream entity = (InputStream) internal.getEntity();
+ try {
+ if (utils.getKey() == Accept.JSON_FULLMETA || utils.getKey() == Accept.ATOM) {
+ entity = utils.getValue().addOperation(entity, "Sack", "#DefaultContainer.Sack",
+ uriInfo.getAbsolutePath().toASCIIString()
+ + "/Microsoft.Test.OData.Services.AstoriaDefaultService.SpecialEmployee/Sack");
+ }
+
+ return utils.getValue().createResponse(
+ uriInfo.getRequestUri().toASCIIString(),
+ entity,
+ internal.getHeaderString("ETag"),
+ utils.getKey());
+ } catch (Exception e) {
+ LOG.error("Error retrieving entity", e);
+ return xml.createFaultResponse(accept, e);
+ }
+ } else {
+ return internal;
+ }
+ }
+
+ @GET
+ @Path("/Product({entityId})")
+ public Response getProduct(
+ @Context final UriInfo uriInfo,
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @PathParam("entityId") final String entityId,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+ final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
+
+ final Response internal = getEntityInternal(
+ uriInfo.getRequestUri().toASCIIString(), accept, "Product", entityId, format, null, null);
+ if (internal.getStatus() == 200) {
+ InputStream entity = (InputStream) internal.getEntity();
+ try {
+ if (utils.getKey() == Accept.JSON_FULLMETA || utils.getKey() == Accept.ATOM) {
+ entity = utils.getValue().addOperation(entity,
+ "ChangeProductDimensions", "#DefaultContainer.ChangeProductDimensions",
+ uriInfo.getAbsolutePath().toASCIIString() + "/ChangeProductDimensions");
+ }
+
+ return utils.getValue().createResponse(
+ uriInfo.getRequestUri().toASCIIString(),
+ entity,
+ internal.getHeaderString("ETag"),
+ utils.getKey());
+ } catch (Exception e) {
+ LOG.error("Error retrieving entity", e);
+ return xml.createFaultResponse(accept, e);
+ }
+ } else {
+ return internal;
+ }
+ }
+
+ @GET
+ @Path("/ComputerDetail({entityId})")
+ public Response getComputerDetail(
+ @Context final UriInfo uriInfo,
@HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
@PathParam("entityId") final String entityId,
@QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+ final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
+
+ final Response internal = getEntityInternal(
+ uriInfo.getRequestUri().toASCIIString(), accept, "ComputerDetail", entityId, format, null, null);
+ if (internal.getStatus() == 200) {
+ InputStream entity = (InputStream) internal.getEntity();
+ try {
+ if (utils.getKey() == Accept.JSON_FULLMETA || utils.getKey() == Accept.ATOM) {
+ entity = utils.getValue().addOperation(entity,
+ "ResetComputerDetailsSpecifications", "#DefaultContainer.ResetComputerDetailsSpecifications",
+ uriInfo.getAbsolutePath().toASCIIString() + "/ResetComputerDetailsSpecifications");
+ }
+
+ return utils.getValue().createResponse(
+ uriInfo.getRequestUri().toASCIIString(),
+ entity,
+ internal.getHeaderString("ETag"),
+ utils.getKey());
+ } catch (Exception e) {
+ LOG.error("Error retrieving entity", e);
+ return xml.createFaultResponse(accept, e);
+ }
+ } else {
+ return internal;
+ }
+ }
+
+ /**
+ * Retrieve entity sample.
+ *
+ * @param accept Accept header.
+ * @param entitySetName Entity set name.
+ * @param entityId entity id.
+ * @param format format query option.
+ * @param expand expand query option.
+ * @param select select query option.
+ * @return entity.
+ */
+ @GET
+ @Path("/{entitySetName}({entityId})")
+ public Response getEntity(
+ @Context final UriInfo uriInfo,
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @PathParam("entitySetName") final String entitySetName,
+ @PathParam("entityId") final String entityId,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
+ @QueryParam("$expand") @DefaultValue(StringUtils.EMPTY) final String expand,
+ @QueryParam("$select") @DefaultValue(StringUtils.EMPTY) final String select) {
+
+ return getEntityInternal(
+ uriInfo.getRequestUri().toASCIIString(), accept, entitySetName, entityId, format, expand, select);
+ }
+
+ protected Response getEntityInternal(
+ final String location,
+ final String accept,
+ final String entitySetName,
+ final String entityId,
+ final String format,
+ final String expand,
+ final String select) {
+
try {
- final Accept acceptType;
- if (StringUtils.isNotBlank(format)) {
- acceptType = Accept.valueOf(format.toUpperCase());
- } else {
- acceptType = Accept.parse(accept);
+ final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
+
+ if (utils.getKey() == Accept.XML || utils.getKey() == Accept.TEXT) {
+ throw new UnsupportedMediaTypeException("Unsupported media type");
}
- final Entity entry = new Entity();
- entry.setType("Microsoft.Test.OData.Services.ODataWCFService.ProductDetail");
- final Property productId = new Property();
- productId.setName("ProductID");
- productId.setType("Edm.Int32");
- productId.setValue(ValueType.PRIMITIVE, Integer.valueOf(entityId));
- entry.getProperties().add(productId);
- final Property productDetailId = new Property();
- productDetailId.setName("ProductDetailID");
- productDetailId.setType("Edm.Int32");
- productDetailId.setValue(ValueType.PRIMITIVE, 2);
- entry.getProperties().add(productDetailId);
+ final Map.Entry<String, InputStream> entityInfo =
+ utils.getValue().readEntity(entitySetName, entityId, Accept.ATOM);
- final Link link = new Link();
- link.setRel("edit");
- link.setHref(URI.create(
- Constants.get(ConstantKey.DEFAULT_SERVICE_URL)
- + "ProductDetails(ProductID=6,ProductDetailID=1)").toASCIIString());
- entry.setEditLink(link);
+ final InputStream entity = entityInfo.getValue();
- final EntityCollection feed = new EntityCollection();
- feed.getEntities().add(entry);
+ ResWrap<Entity> container = atomDeserializer.toEntity(entity);
+ if (container.getContextURL() == null) {
+ container = new ResWrap<Entity>(URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX)
+ + entitySetName + Constants.get(ConstantKey.ODATA_METADATA_ENTITY_SUFFIX)),
+ container.getMetadataETag(), container.getPayload());
+ }
+ final Entity entry = container.getPayload();
- final ResWrap<EntityCollection> container = new ResWrap<EntityCollection>(
- URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX) + "ProductDetail"), null,
- feed);
+ if ((this instanceof KeyAsSegment)) {
+ final Link editLink = new Link();
+ editLink.setRel("edit");
+ editLink.setTitle(entitySetName);
+ editLink.setHref(Constants.get(ConstantKey.DEFAULT_SERVICE_URL) + entitySetName + "/" + entityId);
+
+ entry.setEditLink(editLink);
+ }
+
+ if (StringUtils.isNotBlank(select)) {
+ final List<String> properties = Arrays.asList(select.split(","));
+ final Set<Property> toBeRemoved = new HashSet<Property>();
+
+ for (Property property : entry.getProperties()) {
+ if (!properties.contains(property.getName())) {
+ toBeRemoved.add(property);
+ }
+ }
+
+ entry.getProperties().removeAll(toBeRemoved);
+
+ final Set<Link> linkToBeRemoved = new HashSet<Link>();
+
+ for (Link link : entry.getNavigationLinks()) {
+ if (!properties.contains(link.getTitle().replaceAll("@.*$", "")) && !properties.contains(link.getTitle())) {
+ linkToBeRemoved.add(link);
+ }
+ }
+
+ entry.getNavigationLinks().removeAll(linkToBeRemoved);
+ }
+
+ String tempExpand = expand;
+ if (StringUtils.isNotBlank(tempExpand)) {
+ tempExpand = StringUtils.substringBefore(tempExpand, "(");
+ final List<String> links = Arrays.asList(tempExpand.split(","));
+
+ final Map<Link, Link> replace = new HashMap<Link, Link>();
+
+ for (Link link : entry.getNavigationLinks()) {
+ if (links.contains(link.getTitle())) {
+ // expand link
+ final Link rep = new Link();
+ rep.setHref(link.getHref());
+ rep.setRel(link.getRel());
+ rep.setTitle(link.getTitle());
+ rep.setType(link.getType());
+ if (link.getType().equals(Constants.get(ConstantKey.ATOM_LINK_ENTRY))) {
+ // inline entry
+ final Entity inline = atomDeserializer.toEntity(
+ xml.expandEntity(entitySetName, entityId, link.getTitle())).getPayload();
+ rep.setInlineEntity(inline);
+ } else if (link.getType().equals(Constants.get(ConstantKey.ATOM_LINK_FEED))) {
+ // inline feed
+ final EntityCollection inline = atomDeserializer.toEntitySet(
+ xml.expandEntity(entitySetName, entityId, link.getTitle())).getPayload();
+ rep.setInlineEntitySet(inline);
+ }
+ replace.put(link, rep);
+ }
+ }
+
+ for (Map.Entry<Link, Link> link : replace.entrySet()) {
+ entry.getNavigationLinks().remove(link.getKey());
+ entry.getNavigationLinks().add(link.getValue());
+ }
+ }
return xml.createResponse(
- null,
- xml.writeEntitySet(acceptType, container),
- null,
- acceptType);
+ location,
+ xml.writeEntity(utils.getKey(), container),
+ Commons.getETag(entityInfo.getKey()),
+ utils.getKey());
} catch (Exception e) {
+ LOG.error("Error retrieving entity", e);
return xml.createFaultResponse(accept, e);
}
}
- @POST
- @Path("/Products({entityId})/Microsoft.Test.OData.Services.ODataWCFService.AddAccessRight{paren:[\\(\\)]*}")
- public Response actionAddAccessRight(
+ @GET
+ @Path("/{entitySetName}({entityId})/$value")
+ public Response getMediaEntity(
+ @Context final UriInfo uriInfo,
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @PathParam("entitySetName") final String entitySetName,
+ @PathParam("entityId") final String entityId) {
+
+ try {
+ if (!accept.contains("*/*") && !accept.contains("application/octet-stream")) {
+ throw new UnsupportedMediaTypeException("Unsupported media type");
+ }
+
+ final AbstractUtilities utils = getUtilities(null);
+ final Map.Entry<String, InputStream> entityInfo = utils.readMediaEntity(entitySetName, entityId);
+ return utils.createResponse(
+ uriInfo.getRequestUri().toASCIIString(),
+ entityInfo.getValue(),
+ Commons.getETag(entityInfo.getKey()),
+ null);
+
+ } catch (Exception e) {
+ LOG.error("Error retrieving entity", e);
+ return xml.createFaultResponse(accept, e);
+ }
+ }
+
+ @GET
+ @Path("/People/{type:.*}")
+ public Response getPeople(
+ @Context final UriInfo uriInfo,
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @PathParam("type") final String type,
+ @QueryParam("$top") @DefaultValue(StringUtils.EMPTY) final String top,
+ @QueryParam("$skip") @DefaultValue(StringUtils.EMPTY) final String skip,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
+ @QueryParam("$count") @DefaultValue(StringUtils.EMPTY) final String count,
+ @QueryParam("$filter") @DefaultValue(StringUtils.EMPTY) final String filter,
+ @QueryParam("$search") @DefaultValue(StringUtils.EMPTY) final String search,
+ @QueryParam("$orderby") @DefaultValue(StringUtils.EMPTY) final String orderby,
+ @QueryParam("$skiptoken") @DefaultValue(StringUtils.EMPTY) final String skiptoken) {
+
+ return StringUtils.isBlank(filter) && StringUtils.isBlank(search) ?
+ NumberUtils.isNumber(type) ?
+ getEntityInternal(uriInfo.getRequestUri().toASCIIString(), accept, "People", type, format, null, null) :
+ getEntitySet(accept, "People", type) :
+ getEntitySet(uriInfo, accept, "People", top, skip, format, count, filter, orderby, skiptoken, type);
+ }
+
+ @GET
+ @Path("/Boss")
+ public Response getSingletonBoss(
+ @Context final UriInfo uriInfo,
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+ return getEntityInternal(
+ uriInfo.getRequestUri().toASCIIString(), accept, "Boss", StringUtils.EMPTY, format, null, null);
+ }
+
+ @GET
+ @Path("/Company")
+ public Response getSingletonCompany(
+ @Context final UriInfo uriInfo,
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+ return getEntityInternal(
+ uriInfo.getRequestUri().toASCIIString(), accept, "Company", StringUtils.EMPTY, format, null, null);
+ }
+
+ @PATCH
+ @Path("/Company")
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
+ public Response patchSingletonCompany(
+ @Context final UriInfo uriInfo,
@HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
@HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
+ @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
+ @HeaderParam("If-Match") @DefaultValue(StringUtils.EMPTY) final String ifMatch,
+ final String changes) {
+
+ return patchEntityInternal(uriInfo, accept, contentType, prefer, ifMatch, "Company", StringUtils.EMPTY, changes);
+ }
+
+ @GET
+ @Path("/Customers")
+ public Response getCustomers(
+ @Context final UriInfo uriInfo,
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
@QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
- final String param) {
+ @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
+ @QueryParam("$deltatoken") @DefaultValue(StringUtils.EMPTY) final String deltatoken) {
try {
final Accept acceptType;
@@ -612,236 +1168,1448 @@ public class Services extends AbstractServices {
acceptType = Accept.parse(accept);
}
- final Accept contentTypeValue = Accept.parse(contentType);
- final Entity entry = xml.readEntity(contentTypeValue, IOUtils.toInputStream(param, Constants.ENCODING));
-
- assert 1 == entry.getProperties().size();
- assert entry.getProperty("accessRight") != null;
+ final InputStream output;
+ if (StringUtils.isBlank(deltatoken)) {
+ final InputStream input = (InputStream) getEntitySet(
+ uriInfo, accept, "Customers", null, null, format, null, null, null, null).getEntity();
+ final EntityCollection entitySet = xml.readEntitySet(acceptType, input);
- final Property property = entry.getProperty("accessRight");
- property.setType("Microsoft.Test.OData.Services.ODataWCFService.AccessLevel");
+ boolean trackChanges = prefer.contains("odata.track-changes");
+ if (trackChanges) {
+ entitySet.setDeltaLink(URI.create("Customers?$deltatoken=8015"));
+ }
- final ResWrap<Property> result = new ResWrap<Property>(
- URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX) + property.getType()),
- null, property);
+ output = xml.writeEntitySet(acceptType, new ResWrap<EntityCollection>(
+ URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX) + "Customers"),
+ null,
+ entitySet));
+ } else {
+ output = FSManager.instance().readFile("delta", acceptType);
+ }
- return xml.createResponse(
+ final Response response = xml.createResponse(
null,
- xml.writeProperty(acceptType, result),
+ output,
null,
acceptType);
+ if (StringUtils.isNotBlank(prefer)) {
+ response.getHeaders().put("Preference-Applied", Collections.<Object> singletonList(prefer));
+ }
+ return response;
} catch (Exception e) {
return xml.createFaultResponse(accept, e);
}
}
@POST
- @Path("/Customers({personId})/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress{paren:[\\(\\)]*}")
- public Response actionResetAddress(
+ @Path("/{entitySetName}")
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM })
+ public Response postNewEntity(
@Context final UriInfo uriInfo,
@HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @PathParam("personId") final String personId,
+ @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
+ @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
+ @PathParam("entitySetName") final String entitySetName,
+ final String entity) {
+
+ try {
+ final Accept acceptType = Accept.parse(accept);
+ if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
+ throw new UnsupportedMediaTypeException("Unsupported media type");
+ }
+
+ final ResWrap<Entity> container;
+
+ final org.apache.olingo.fit.metadata.EntitySet entitySet = metadata.getEntitySet(entitySetName);
+
+ final Entity entry;
+ final String entityKey;
+ if (xml.isMediaContent(entitySetName)) {
+ entry = new Entity();
+ entry.setMediaContentType(ContentType.APPLICATION_OCTET_STREAM.toContentTypeString());
+ entry.setType(entitySet.getType());
+
+ entityKey = xml.getDefaultEntryKey(entitySetName, entry);
+
+ xml.addMediaEntityValue(entitySetName, entityKey, IOUtils.toInputStream(entity, Constants.ENCODING));
+
+ final Pair<String, EdmPrimitiveTypeKind> id = Commons.getMediaContent().get(entitySetName);
+ if (id != null) {
+ final Property prop = new Property();
+ prop.setName(id.getKey());
+ prop.setType(id.getValue().toString());
+ prop.setValue(ValueType.PRIMITIVE,
+ id.getValue() == EdmPrimitiveTypeKind.Int32
+ ? Integer.parseInt(entityKey)
+ : id.getValue() == EdmPrimitiveTypeKind.Guid
+ ? UUID.fromString(entityKey)
+ : entityKey);
+ entry.getProperties().add(prop);
+ }
+
+ final Link editLink = new Link();
+ editLink.setHref(Commons.getEntityURI(entitySetName, entityKey));
+ editLink.setRel("edit");
+ editLink.setTitle(entitySetName);
+ entry.setEditLink(editLink);
+
+ entry.setMediaContentSource(URI.create(editLink.getHref() + "/$value"));
+
+ container = new ResWrap<Entity>((URI) null, null, entry);
+ } else {
+ final Accept contentTypeValue = Accept.parse(contentType);
+ if (Accept.ATOM == contentTypeValue) {
+ container = atomDeserializer.toEntity(IOUtils.toInputStream(entity, Constants.ENCODING));
+ } else {
+ container = jsonDeserializer.toEntity(IOUtils.toInputStream(entity, Constants.ENCODING));
+ }
+ entry = container.getPayload();
+ updateInlineEntities(entry);
+
+ entityKey = xml.getDefaultEntryKey(entitySetName, entry);
+ }
+
+ normalizeAtomEntry(entry, entitySetName, entityKey);
+
+ final ByteArrayOutputStream content = new ByteArrayOutputStream();
+ final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING);
+ atomSerializer.write(writer, container);
+ writer.flush();
+ writer.close();
+
+ final InputStream serialization =
+ xml.addOrReplaceEntity(entityKey, entitySetName, new ByteArrayInputStream(content.toByteArray()), entry);
+
+ ResWrap<Entity> result = atomDeserializer.toEntity(serialization);
+ result = new ResWrap<Entity>(
+ URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX)
+ + entitySetName + Constants.get(ConstantKey.ODATA_METADATA_ENTITY_SUFFIX)),
+ null, result.getPayload());
+
+ final String path = Commons.getEntityBasePath(entitySetName, entityKey);
+ FSManager.instance().putInMemory(result, path + Constants.get(ConstantKey.ENTITY));
+
+ final String location;
+
+ if ((this instanceof KeyAsSegment)) {
+ location = uriInfo.getRequestUri().toASCIIString() + "/" + entityKey;
+
+ final Link editLink = new Link();
+ editLink.setRel("edit");
+ editLink.setTitle(entitySetName);
+ editLink.setHref(location);
+
+ result.getPayload().setEditLink(editLink);
+ } else {
+ location = uriInfo.getRequestUri().toASCIIString() + "(" + entityKey + ")";
+ }
+
+ final Response response;
+ if ("return-no-content".equalsIgnoreCase(prefer)) {
+ response = xml.createResponse(
+ location,
+ null,
+ null,
+ acceptType,
+ Response.Status.NO_CONTENT);
+ } else {
+ response = xml.createResponse(
+ location,
+ xml.writeEntity(acceptType, result),
+ null,
+ acceptType,
+ Response.Status.CREATED);
+ }
+
+ if (StringUtils.isNotBlank(prefer)) {
+ response.getHeaders().put("Preference-Applied", Collections.<Object> singletonList(prefer));
+ }
+
+ return response;
+ } catch (Exception e) {
+ LOG.error("While creating new entity", e);
+ return xml.createFaultResponse(accept, e);
+ }
+ }
+
+ private void updateInlineEntities(final Entity entity) {
+ final String type = entity.getType();
+ EntityType entityType;
+ Map<String, NavigationProperty> navProperties = Collections.emptyMap();
+ if (type != null && type.length() > 0) {
+ entityType = metadata.getEntityOrComplexType(type);
+ navProperties = entityType.getNavigationPropertyMap();
+ }
+
+ for (Property property : entity.getProperties()) {
+ if (navProperties.containsKey(property.getName())) {
+ Link alink = new Link();
+ alink.setTitle(property.getName());
+ alink.getAnnotations().addAll(property.getAnnotations());
+
+ alink.setType(navProperties.get(property.getName()).isEntitySet()
+ ? Constants.get(ConstantKey.ATOM_LINK_FEED)
+ : Constants.get(ConstantKey.ATOM_LINK_ENTRY));
+
+ alink.setRel(Constants.get(ConstantKey.ATOM_LINK_REL) + property.getName());
+
+ if (property.isCollection()) {
+ EntityCollection inline = new EntityCollection();
+ for (Object value : property.asCollection()) {
+ Entity inlineEntity = new Entity();
+ inlineEntity.setType(navProperties.get(property.getName()).getType());
+ for (Property prop : ((ComplexValue) value).getValue()) {
+ inlineEntity.getProperties().add(prop);
+ }
+ inline.getEntities().add(inlineEntity);
+ }
+ alink.setInlineEntitySet(inline);
+ } else if (property.isComplex()) {
+ Entity inline = new Entity();
+ inline.setType(navProperties.get(property.getName()).getType());
+ for (Property prop : property.asComplex().getValue()) {
+ inline.getProperties().add(prop);
+ }
+ alink.setInlineEntity(inline);
+
+ } else {
+ throw new IllegalStateException("Invalid navigation property " + property);
+ }
+ entity.getNavigationLinks().add(alink);
+ }
+ }
+ }
+
+ private void normalizeAtomEntry(final Entity entry, final String entitySetName, final String entityKey) {
+ final org.apache.olingo.fit.metadata.EntitySet entitySet = metadata.getEntitySet(entitySetName);
+ final EntityType entityType = metadata.getEntityOrComplexType(entitySet.getType());
+ for (Map.Entry<String, org.apache.olingo.fit.metadata.Property> property : entityType.getPropertyMap().entrySet()) {
+ if (entry.getProperty(property.getKey()) == null && property.getValue().isNullable()) {
+ final Property prop = new Property();
+ prop.setName(property.getKey());
+ prop.setValue(ValueType.PRIMITIVE, null);
+ entry.getProperties().add(prop);
+ }
+ }
+
+ for (Map.Entry<String, NavigationProperty> property : entityType.getNavigationPropertyMap().entrySet()) {
+ boolean found = false;
+ for (Link link : entry.getNavigationLinks()) {
+ if (link.getTitle().equals(property.getKey())) {
+ found = true;
+ }
+ }
+
+ if (!found) {
+ final Link link = new Link();
+ link.setTitle(property.getKey());
+ link.setType(property.getValue().isEntitySet()
+ ? Constants.get(ConstantKey.ATOM_LINK_FEED)
+ : Constants.get(ConstantKey.ATOM_LINK_ENTRY));
+ link.setRel(Constants.get(ConstantKey.ATOM_LINK_REL) + property.getKey());
+ link.setHref(entitySetName + "(" + entityKey + ")/" + property.getKey());
+ entry.getNavigationLinks().add(link);
+ }
+ }
+ }
+
+ @GET
+ @Path("/Company/Microsoft.Test.OData.Services.ODataWCFService.GetEmployeesCount{paren:[\\(\\)]*}")
+ public Response functionGetEmployeesCount(
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+ try {
+ final Accept acceptType;
+ if (StringUtils.isNotBlank(format)) {
+ acceptType = Accept.valueOf(format.toUpperCase());
+ } else {
+ acceptType = Accept.parse(accept);
+ }
+
+ final Property property = new Property();
+ property.setType("Edm.Int32");
+ property.setValue(ValueType.PRIMITIVE, 2);
+ final ResWrap<Property> container = new ResWrap<Property>(
+ URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX) + property.getType()), null,
+ property);
+
+ return xml.createResponse(
+ null,
+ xml.writeProperty(acceptType, container),
+ null,
+ acceptType);
+ } catch (Exception e) {
+ return xml.createFaultResponse(accept, e);
+ }
+ }
+
+ @POST
+ @Path("/Person({entityId})/{type:.*}/Sack")
+ public Response actionSack(
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @PathParam("entityId") final String entityId,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+ final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
+
+ if (utils.getKey() == Accept.XML || utils.getKey() == Accept.TEXT) {
+ throw new UnsupportedMediaTypeException("Unsupported media type");
+ }
+
+ try {
+ final Map.Entry<String, InputStream> entityInfo = xml.readEntity("Person", entityId, Accept.ATOM);
+
+ final InputStream entity = entityInfo.getValue();
+ final ResWrap<Entity> container = atomDeserializer.toEntity(entity);
+
+ container.getPayload().getProperty("Salary").setValue(ValueType.PRIMITIVE, 0);
+ container.getPayload().getProperty("Title").setValue(ValueType.PRIMITIVE, "[Sacked]");
+
+ final FSManager fsManager = FSManager.instance();
+ fsManager.putInMemory(xml.writeEntity(Accept.ATOM, container),
+ fsManager.getAbsolutePath(Commons.getEntityBasePath("Person", entityId) + Constants.get(
+ ConstantKey.ENTITY), Accept.ATOM));
+
+ return utils.getValue().createResponse(null, null, null, utils.getKey(), Response.Status.NO_CONTENT);
+ } catch (Exception e) {
+ return xml.createFaultResponse(accept, e);
+ }
+ }
+
+ @POST
+ @Path("/Person/{type:.*}/IncreaseSalaries")
+ public Response actionIncreaseSalaries(
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @PathParam("type") final String type,
+ final String body) {
+
+ final String name = "Person";
+ try {
+ final Accept acceptType = Accept.parse(accept);
+ if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
+ throw new UnsupportedMediaTypeException("Unsupported media type");
+ }
+
+ final JsonNode tree = new ObjectMapper().readTree(body);
+ if (!tree.has("n")) {
+ throw new Exception("Missing parameter: n");
+ }
+ final int n = tree.get("n").asInt();
+
+ final StringBuilder path = new StringBuilder(name).
+ append(File.separatorChar).append(type).
+ append(File.separatorChar);
+
+ path.append(metadata.getEntitySet(name).isSingleton()
+ ? Constants.get(ConstantKey.ENTITY)
+ : Constants.get(ConstantKey.FEED));
+
+ final InputStream feed = FSManager.instance().readFile(path.toString(), acceptType);
+
+ final ByteArrayOutputStream copy = new ByteArrayOutputStream();
+ IOUtils.copy(feed, copy);
+ IOUtils.closeQuietly(feed);
+
+ String newContent = new String(copy.toByteArray(), "UTF-8");
+ final Pattern salary = Pattern.compile(acceptType == Accept.ATOM
+ ? "\\<d:Salary m:type=\"Edm.Int32\"\\>(-?\\d+)\\</d:Salary\\>"
+ : "\"Salary\":(-?\\d+),");
+ final Matcher salaryMatcher = salary.matcher(newContent);
+ while (salaryMatcher.find()) {
+ final Long newSalary = Long.valueOf(salaryMatcher.group(1)) + n;
+ newContent = newContent.
+ replaceAll("\"Salary\":" + salaryMatcher.group(1) + ",",
+ "\"Salary\":" + newSalary + ",").
+ replaceAll("\\<d:Salary m:type=\"Edm.Int32\"\\>" + salaryMatcher.group(1) + "</d:Salary\\>",
+ "<d:Salary m:type=\"Edm.Int32\">" + newSalary + "</d:Salary>");
+ }
+
+ FSManager.instance().putInMemory(IOUtils.toInputStream(newContent, Constants.ENCODING),
+ FSManager.instance().getAbsolutePath(path.toString(), acceptType));
+
+ return xml.createResponse(null, null, null, acceptType, Response.Status.NO_CONTENT);
+ } catch (Exception e) {
+ return xml.createFaultResponse(accept, e);
+ }
+ }
+
+ @POST
+ @Path("/Product({entityId})/ChangeProductDimensions")
+ public Response actionChangeProductDimensions(
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @PathParam("entityId") final String entityId,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
+ final String argument) {
+
+ final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
+
+ if (utils.getKey() == Accept.XML || utils.getKey() == Accept.TEXT) {
+ throw new UnsupportedMediaTypeException("Unsupported media type");
+ }
+
+ try {
+ final Map.Entry<String, InputStream> entityInfo = xml.readEntity("Product", entityId, Accept.ATOM);
+
+ final InputStream entity = entityInfo.getValue();
+ final ResWrap<Entity> container = atomDeserializer.toEntity(entity);
+
+ final Entity param = xml.readEntity(utils.getKey(), IOUtils.toInputStream(argument, Constants.ENCODING));
+
+ final Property property = param.getProperty("dimensions");
+ container.getPayload().getProperty("Dimensions").setValue(property.getValueType(), property.getValue());
+
+ final FSManager fsManager = FSManager.instance();
+ fsManager.putInMemory(xml.writeEntity(Accept.ATOM, container),
+ fsManager.getAbsolutePath(Commons.getEntityBasePath("Product", entityId) + Constants.get(
+ ConstantKey.ENTITY), Accept.ATOM));
+
+ return utils.getValue().createResponse(null, null, null, utils.getKey(), Response.Status.NO_CONTENT);
+ } catch (Exception e) {
+ return xml.createFaultResponse(accept, e);
+ }
+ }
+
+ @POST
+ @Path("/ComputerDetail({entityId})/ResetComputerDetailsSpecifications")
+ public Response actionResetComputerDetailsSpecifications(
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @PathParam("entityId") final String entityId,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
+ final String argument) {
+
+ final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
+
+ if (utils.getKey() == Accept.XML || utils.getKey() == Accept.TEXT) {
+ throw new UnsupportedMediaTypeException("Unsupported media type");
+ }
+
+ try {
+ final Map.Entry<String, InputStream> entityInfo = xml.readEntity("ComputerDetail", entityId, Accept.ATOM);
+
+ final InputStream entity = entityInfo.getValue();
+ final ResWrap<Entity> container = atomDeserializer.toEntity(entity);
+
+ final Entity param = xml.readEntity(utils.getKey(), IOUtils.toInputStream(argument, Constants.ENCODING));
+
+ Property property = param.getProperty("specifications");
+ container.getPayload().getProperty("SpecificationsBag").setValue(property.getValueType(), property.getValue());
+ property = param.getProperty("purchaseTime");
+ container.getPayload().getProperty("PurchaseDate").setValue(property.getValueType(), property.getValue());
+
+ final FSManager fsManager = FSManager.instance();
+ fsManager.putInMemory(xml.writeEntity(Accept.ATOM, container),
+ fsManager.getAbsolutePath(Commons.getEntityBasePath("ComputerDetail", entityId) + Constants.get(
+ ConstantKey.ENTITY), Accept.ATOM));
+
+ return utils.getValue().createResponse(null, null, null, utils.getKey(), Response.Status.NO_CONTENT);
+ } catch (Exception e) {
+ return xml.createFaultResponse(accept, e);
+ }
+ }
+
+ @POST
+ @Path("/Company/Microsoft.Test.OData.Services.ODataWCFService.IncreaseRevenue{paren:[\\(\\)]*}")
+ public Response actionIncreaseRevenue(
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
@HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
@QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
final String param) {
try {
+ final Accept acceptType;
+ if (StringUtils.isNotBlank(format)) {
+ acceptType = Accept.valueOf(format.toUpperCase());
+ } else {
+ acceptType = Accept.parse(accept);
+ }
+
final Accept contentTypeValue = Accept.parse(contentType);
final Entity entry = xml.readEntity(contentTypeValue, IOUtils.toInputStream(param, Constants.ENCODING));
- assert 2 == entry.getProperties().size();
- assert entry.getProperty("addresses") != null;
- assert entry.getProperty("index") != null;
+ return xml.createResponse(
+ null,
+ xml.writeProperty(acceptType, entry.getProperty("IncreaseValue")),
+ null,
+ acceptType);
+ } catch (Exception e) {
+ return xml.createFaultResponse(accept, e);
+ }
+ }
+
+ @GET
+ @Path("/Products({entityId})/Microsoft.Test.OData.Services.ODataWCFService.GetProductDetails({param:.*})")
+ public Response functionGetProductDetails(
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @PathParam("entityId") final String entityId,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+ try {
+ final Accept acceptType;
+ if (StringUtils.isNotBlank(format)) {
+ acceptType = Accept.valueOf(format.toUpperCase());
+ } else {
+ acceptType = Accept.parse(accept);
+ }
+
+ final Entity entry = new Entity();
+ entry.setType("Microsoft.Test.OData.Services.ODataWCFService.ProductDetail");
+ final Property productId = new Property();
+ productId.setName("ProductID");
+ productId.setType("Edm.Int32");
+ productId.setValue(ValueType.PRIMITIVE, Integer.valueOf(entityId));
+ entry.getProperties().add(productId);
+ final Property productDetailId = new Property();
+ productDetailId.setName("ProductDetailID");
+ productDetailId.setType("Edm.Int32");
+ productDetailId.setValue(ValueType.PRIMITIVE, 2);
+ entry.getProperties().add(productDetailId);
+
+ final Link link = new Link();
+ link.setRel("edit");
+ link.setHref(URI.create(
+ Constants.get(ConstantKey.DEFAULT_SERVICE_URL)
+ + "ProductDetails(ProductID=6,ProductDetailID=1)").toASCIIString());
+ entry.setEditLink(link);
+
+ final EntityCollection feed = new EntityCollection();
+ feed.getEntities().add(entry);
+
+ final ResWrap<EntityCollection> container = new ResWrap<EntityCollection>(
+ URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX) + "ProductDetail"), null,
+ feed);
+
+ return xml.createResponse(
+ null,
+ xml.writeEntitySet(acceptType, container),
+ null,
+ acceptType);
+ } catch (Exception e) {
+ return xml.createFaultResponse(accept, e);
+ }
+ }
+
+ @POST
+ @Path("/Products({entityId})/Microsoft.Test.OData.Services.ODataWCFService.AddAccessRight{paren:[\\(\\)]*}")
+ public Response actionAddAccessRight(
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
+ final String param) {
+
+ try {
+ final Accept acceptType;
+ if (StringUtils.isNotBlank(format)) {
+ acceptType = Accept.valueOf(format.toUpperCase());
+ } else {
+ acceptType = Accept.parse(accept);
+ }
+
+ final Accept contentTypeValue = Accept.parse(contentType);
+ final Entity entry = xml.readEntity(contentTypeValue, IOUtils.toInputStream(param, Constants.ENCODING));
+
+ assert 1 == entry.getProperties().size();
+ assert entry.getProperty("accessRight") != null;
+
+ final Property property = entry.getProperty("accessRight");
+ property.setType("Microsoft.Test.OData.Services.ODataWCFService.AccessLevel");
+
+ final ResWrap<Property> result = new ResWrap<Property>(
+ URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX) + property.getType()),
+ null, property);
+
+ return xml.createResponse(
+ null,
+ xml.writeProperty(acceptType, result),
+ null,
+ acceptType);
+ } catch (Exception e) {
+ return xml.createFaultResponse(accept, e);
+ }
+ }
+
+ @POST
+ @Path("/Customers({personId})/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress{paren:[\\(\\)]*}")
+ public Response actionResetAddress(
+ @Context final UriInfo uriInfo,
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @PathParam("personId") final String personId,
+ @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
+ final String param) {
+
+ try {
+ final Accept contentTypeValue = Accept.parse(contentType);
+ final Entity entry = xml.readEntity(contentTypeValue, IOUtils.toInputStream(param, Constants.ENCODING));
+
+ assert 2 == entry.getProperties().size();
+ assert entry.getProperty("addresses") != null;
+ assert entry.getProperty("index") != null;
+
+ return getEntityInternal(
+ uriInfo.getRequestUri().toASCIIString(), accept, "Customers", personId, format, null, null);
+ } catch (Exception e) {
+ return xml.createFaultResponse(accept, e);
+ }
+ }
+
+ @GET
+ @Path("/ProductDetails(ProductID={productId},ProductDetailID={productDetailId})"
+ + "/Microsoft.Test.OData.Services.ODataWCFService.GetRelatedProduct{paren:[\\(\\)]*}")
+ public Response functionGetRelatedProduct(
+ @Context final UriInfo uriInfo,
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @PathParam("productId") final String productId,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+ return getEntityInternal(
+ uriInfo.getRequestUri().toASCIIString(), accept, "Products", productId, format, null, null);
+ }
+
+ @POST
+ @Path("/Accounts({entityId})/Microsoft.Test.OData.Services.ODataWCFService.RefreshDefaultPI{paren:[\\(\\)]*}")
+ public Response actionRefreshDefaultPI(
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
+ @PathParam("entityId") final String entityId,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
+ final String param) {
+
+ try {
+ final Accept contentTypeValue = Accept.parse(contentType);
+ final Entity entry = xml.readEntity(contentTypeValue, IOUtils.toInputStream(param, Constants.ENCODING));
+
+ assert 1 == entry.getProperties().size();
+ assert entry.getProperty("newDate") != null;
+
+ return functionGetDefaultPI(accept, entityId, format);
+ } catch (Exception e) {
+ return xml.createFaultResponse(accept, e);
+ }
+ }
+
+ @GET
+ @Path("/Accounts({entityId})/Microsoft.Test.OData.Services.ODataWCFService.GetDefaultPI{paren:[\\(\\)]*}")
+ public Response functionGetDefaultPI(
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @PathParam("entityId") final String entityId,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+ return getContainedEntity(accept, entityId, "MyPaymentInstruments", entityId + "901", format);
+ }
+
+ @GET
+ @Path("/Accounts({entityId})/Microsoft.Test.OData.Services.ODataWCFService.GetAccountInfo{paren:[\\(\\)]*}")
+ public Response functionGetAccountInfo(
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @PathParam("entityId") final String entityId,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+ return getPath(accept, "Accounts", entityId, "AccountInfo", format);
+ }
+
+ @GET
+ @Path("/Accounts({entityId})/MyGiftCard/Microsoft.Test.OData.Services.ODataWCFService.GetActualAmount({param:.*})")
+ public Response functionGetActualAmount(
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+ try {
+ final Accept acceptType;
+ if (StringUtils.isNotBlank(format)) {
+ acceptType = Accept.valueOf(format.toUpperCase());
+ } else {
+ acceptType = Accept.parse(accept);
+ }
+
+ final Property property = new Property();
+ property.setType("Edm.Double");
+ property.setValue(ValueType.PRIMITIVE, 41.79);
+
+ final ResWrap<Property> container = new ResWrap<Property>((URI) null, null, property);
+
+ return xml.createResponse(
+ null,
+ xml.writeProperty(acceptType, container),
+ null,
+ acceptType);
+ } catch (Exception e) {
+ return xml.createFaultResponse(accept, e);
+ }
+ }
+
+ /**
+ * Retrieve entity reference sample.
+ *
+ * @param accept Accept header.
+ * @param path path.
+ * @param format format query option.
+ * @return entity reference or feed of entity reference.
+ */
+ @GET
+ @Path("/{path:.*}/$ref")
+ public Response getEntityReference(
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @PathParam("path") final String path,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+ try {
+ final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
+
+ if (utils.getKey() == Accept.TEXT) {
+ throw new UnsupportedMediaTypeException("Unsupported media type");
+ }
+
+ final String filename = Base64.encodeBase64String(path.getBytes("UTF-8"));
+
+ return utils.getValue().createResponse(
+ FSManager.instance().readFile(Constants.get(ConstantKey.REF)
+ + File.separatorChar + filename, utils.getKey()),
+ null,
+ utils.getKey());
+ } catch (Exception e) {
+ LOG.error("Error retrieving entity", e);
+ return xml.createFaultResponse(accept, e);
+ }
+ }
+
+ @POST
+ @Path("/People")
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM })
+ public Response postPeople(
+ @Context final UriInfo uriInfo,
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
+ @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
+ final String entity) {
+
+ if ("{\"@odata.type\":\"#Microsoft.Test.OData.Services.ODataWCFService.Person\"}".equals(entity)) {
+ return xml.createFaultResponse(accept, new BadRequestException());
+ }
+
+ return postNewEntity(uriInfo, accept, contentType, prefer, "People", entity);
+ }
+
+ private Response patchEntityInternal(final UriInfo uriInfo,
+ final String accept, final String contentType, final String prefer, final String ifMatch,
+ final String entitySetName, final String entityId, final String changes) {
+
+ try {
+ final Accept acceptType = Accept.parse(accept);
+
+ if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
+ throw new UnsupportedMediaTypeException("Unsupported media type");
+ }
+
+ final Map.Entry<String, InputStream> entityInfo = xml.readEntity(entitySetName, entityId, Accept.ATOM);
+
+ final String etag = Commons.getETag(entityInfo.getKey());
+ if (StringUtils.isNotBlank(ifMatch) && !ifMatch.equals(etag)) {
+ throw new ConcurrentModificationException("Concurrent modification");
+ }
+
+ final Accept contentTypeValue = Accept.parse(contentType);
+
+ final Entity entryChanges;
+
+ if (contentTypeValue == Accept.XML || contentTypeValue == Accept.TEXT) {
+ throw new UnsupportedMediaTypeException("Unsupported media type");
+ } else if (contentTypeValue == Accept.ATOM) {
+ entryChanges = atomDeserializer.toEntity(
+ IOUtils.toInputStream(changes, Constants.ENCODING)).getPayload();
+ } else {
+ final ResWrap<Entity> jcont = jsonDeserializer.toEntity(IOUtils.toInputStream(changes, Constants.ENCODING));
+ entryChanges = jcont.getPayload();
+ }
+
+ final ResWrap<Entity> container = atomDeserializer.toEntity(entityInfo.getValue());
+
+ for (Property property : entryChanges.getProperties()) {
+ final Property _property = container.getPayload().getProperty(property.getName());
+ if (_property == null) {
+ container.getPayload().getProperties().add(property);
+ } else {
+ _property.setValue(property.getValueType(), property.getValue());
+ }
+ }
+
+ for (Link link : entryChanges.getNavigationLinks()) {
+ container.getPayload().getNavigationLinks().add(link);
+ }
+
+ final ByteArrayOutputStream content = new ByteArrayOutputStream();
+ final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING);
+ atomSerializer.write(writer, container);
+ writer.flush();
+ writer.close();
+
+ final InputStream res = xml.addOrReplaceEntity(
+ entityId, entitySetName, new ByteArrayInputStream(content.toByteArray()), container.getPayload());
+
+ final ResWrap<Entity> cres = atomDeserializer.toEntity(res);
+
+ normalizeAtomEntry(cres.getPayload(), entitySetName, entityId);
+
+ final String path = Commons.getEntityBasePath(entitySetName, entityId);
+ FSManager.instance().putInMemory(
+ cres, path + File.separatorChar + Constants.get(ConstantKey.ENTITY));
+
+ final Response response;
+ if ("return-content".equalsIgnoreCase(prefer)) {
+ response = xml.createResponse(
+ uriInfo.getRequestUri().toASCIIString(),
+ xml.readEntity(entitySetName, entityId, acceptType).getValue(),
+ null, acceptType, Response.Status.OK);
+ } else {
+ res.close();
+ response = xml.createResponse(
+ uriInfo.getRequestUri().toASCIIString(),
+ null,
+ null,
+ acceptType, Response.Status.NO_CONTENT);
+ }
+
+ if (StringUtils.isNotBlank(prefer)) {
+ response.getHeaders().put("Preference-Applied", Collections.<Object> singletonList(prefer));
+ }
+
+ return response;
+ } catch (Exception e) {
+ return xml.createFaultResponse(accept, e);
+ }
+ }
+
+ @PATCH
+ @Path("/{entitySetName}({entityId})")
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
+ public Response patchEntity(
+ @Context final UriInfo uriInfo,
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
+ @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
+ @HeaderParam("If-Match") @DefaultValue(StringUtils.EMPTY) final String ifMatch,
+ @PathParam("entitySetName") final String entitySetName,
+ @PathParam("entityId") final String entityId,
+ final String changes) {
+
+ final Response response =
+ getEntityInternal(uriInfo.getRequestUri().toASCIIString(),
+ accept, entitySetName, entityId, accept, StringUtils.EMPTY, StringUtils.EMPTY);
+ return response.getStatus() >= 400 ?
+ postNewEntity(uriInfo, accept, contentType, prefer, entitySetName, changes) :
+ patchEntityInternal(uriInfo, accept, contentType, prefer, ifMatch, entitySetName, entityId, changes);
+ }
+
+ private Response replaceEntity(final UriInfo uriInfo,
+ final String accept, final String prefer,
+ final String entitySetName, final String entityId, final String entity) {
+
+ try {
+ final Accept acceptType = Accept.parse(accept);
+
+ if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
+ throw new UnsupportedMediaTypeException("Unsupported media type");
+ }
+
+ final InputStream res = getUtilities(acceptType).addOrReplaceEntity(entityId, entitySetName,
+ IOUtils.toInputStream(entity, Constants.ENCODING),
+ xml.readEntity(acceptType, IOUtils.toInputStream(entity, Constants.ENCODING)));
+
+ final ResWrap<Entity> cres;
+ if (acceptType == Accept.ATOM) {
+ cres = atomDeserializer.toEntity(res);
+ } else {
+ cres = jsonDeserializer.toEntity(res);
+ }
+
+ final String path = Commons.getEntityBasePath(entitySetName, entityId);
+ FSManager.instance().putInMemory(
+ cres, path + File.separatorChar + Constants.get(ConstantKey.ENTITY));
+
+ final Response response;
+ if ("return-content".equalsIgnoreCase(prefer)) {
+ response = xml.createResponse(
+ uriInfo.getRequestUri().toASCIIString(),
+ xml.readEntity(entitySetName, entityId, acceptType).getValue(),
+ null,
+ acceptType,
+ Response.Status.OK);
+ } else {
+ res.close();
+ response = xml.createResponse(
+ uriInfo.getRequestUri().toASCIIString(),
+ null,
+ null,
+ acceptType,
+ Response.Status.NO_CONTENT);
+ }
+
+ if (StringUtils.isNotBlank(prefer)) {
+ response.getHeaders().put("Preference-Applied", Collections.<Object> singletonList(prefer));
+ }
+
+ return response;
+ } catch (Exception e) {
+ return xml.createFaultResponse(accept, e);
+ }
+ }
+
+ @PUT
+ @Path("/{entitySetName}({entityId})")
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
+ public Response replaceEntity(
+ @Context final UriInfo uriInfo,
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
+ @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
+ @PathParam("entitySetName") final String entitySetName,
+ @PathParam("entityId") final String entityId,
+ final String entity) {
+
+ try {
+ getEntityInternal(uriInfo.getRequestUri().toASCIIString(),
+ accept, entitySetName, entityId, accept, StringUtils.EMPTY, StringUtils.EMPTY);
+ return replaceEntity(uriInfo, accept, prefer, entitySetName, entityId, entity);
+ } catch (NotFoundException e) {
+ return postNewEntity(uriInfo, accept, contentType, prefer, entitySetName, entityId);
+ }
+ }
+
+ private StringBuilder containedPath(final String entityId, final String containedEntitySetName) {
+ return new StringBuilder("Accounts").append(File.separatorChar).
+ append(entityId).append(File.separatorChar).
+ appen
<TRUNCATED>
[12/22] olingo-odata4 git commit: OLINGO-861, OLINGO-863, OLINGO-868,
OLINGO-869 : Improvements to MetadataParser for annotation support
Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6d94f0e3/lib/server-core-ext/src/test/resources/trippin.xml
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/resources/trippin.xml b/lib/server-core-ext/src/test/resources/trippin.xml
index 5970793..3266344 100644
--- a/lib/server-core-ext/src/test/resources/trippin.xml
+++ b/lib/server-core-ext/src/test/resources/trippin.xml
@@ -1,356 +1,458 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
-
- 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.
-
--->
+<!-- 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. -->
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
- <edmx:DataServices>
- <Schema Namespace="Microsoft.OData.SampleService.Models.TripPin" xmlns="http://docs.oasis-open.org/odata/ns/edm">
- <EnumType Name="PersonGender">
- <Member Name="Male" Value="0" />
- <Member Name="Female" Value="1" />
- <Member Name="Unknown" Value="2" />
- </EnumType>
- <ComplexType Name="City">
- <Property Name="CountryRegion" Type="Edm.String" Nullable="false" />
- <Property Name="Name" Type="Edm.String" Nullable="false" />
- <Property Name="Region" Type="Edm.String" Nullable="false" />
- </ComplexType>
- <ComplexType Name="Location" OpenType="true">
- <Property Name="Address" Type="Edm.String" Nullable="false" />
- <Property Name="City" Type="Microsoft.OData.SampleService.Models.TripPin.City" Nullable="false" />
- </ComplexType>
- <ComplexType Name="EventLocation" BaseType="Microsoft.OData.SampleService.Models.TripPin.Location" OpenType="true">
- <Property Name="BuildingInfo" Type="Edm.String" />
- </ComplexType>
- <ComplexType Name="AirportLocation" BaseType="Microsoft.OData.SampleService.Models.TripPin.Location" OpenType="true">
- <Property Name="Loc" Type="Edm.GeographyPoint" Nullable="false" SRID="4326" />
- </ComplexType>
- <EntityType Name="Photo" HasStream="true">
- <Key>
- <PropertyRef Name="Id" />
- </Key>
- <Property Name="Id" Type="Edm.Int64" Nullable="false">
- <Annotation Term="Org.OData.Core.V1.Permissions">
- <EnumMember>Org.OData.Core.V1.Permission/Read</EnumMember>
- </Annotation>
- </Property>
- <Property Name="Name" Type="Edm.String" />
- <Annotation Term="Org.OData.Core.V1.AcceptableMediaTypes">
- <Collection>
- <String>image/jpeg</String>
- </Collection>
- </Annotation>
- </EntityType>
- <EntityType Name="Person" OpenType="true">
- <Key>
- <PropertyRef Name="UserName" />
- </Key>
- <Property Name="UserName" Type="Edm.String" Nullable="false">
- <Annotation Term="Org.OData.Core.V1.Permissions">
- <EnumMember>Org.OData.Core.V1.Permission/Read</EnumMember>
- </Annotation>
- </Property>
- <Property Name="FirstName" Type="Edm.String" Nullable="true" />
- <Property Name="LastName" Type="Edm.String" Nullable="false" />
- <Property Name="Emails" Type="Collection(Edm.String)" />
- <Property Name="AddressInfo" Type="Collection(Microsoft.OData.SampleService.Models.TripPin.Location)" />
- <Property Name="Gender" Type="Microsoft.OData.SampleService.Models.TripPin.PersonGender" />
- <Property Name="Concurrency" Type="Edm.Int64" Nullable="false">
- <Annotation Term="Org.OData.Core.V1.Computed" Bool="true" />
- </Property>
- <NavigationProperty Name="Friends" Type="Collection(Microsoft.OData.SampleService.Models.TripPin.Person)" />
- <NavigationProperty Name="Trips" Type="Collection(Microsoft.OData.SampleService.Models.TripPin.Trip)" ContainsTarget="true" />
- <NavigationProperty Name="Photo" Type="Microsoft.OData.SampleService.Models.TripPin.Photo" />
- </EntityType>
- <EntityType Name="Airline">
- <Key>
- <PropertyRef Name="AirlineCode" />
- </Key>
- <Property Name="AirlineCode" Type="Edm.String" Nullable="false">
- <Annotation Term="Org.OData.Core.V1.Permissions">
- <EnumMember>Org.OData.Core.V1.Permission/Read</EnumMember>
- </Annotation>
- </Property>
- <Property Name="Name" Type="Edm.String" Nullable="false" />
- <Property Name="Picture" Type="Edm.Stream" Nullable="true" />
- </EntityType>
- <EntityType Name="Airport">
- <Key>
- <PropertyRef Name="IcaoCode" />
- </Key>
- <Property Name="IcaoCode" Type="Edm.String" Nullable="false">
- <Annotation Term="Org.OData.Core.V1.Permissions">
- <EnumMember>Org.OData.Core.V1.Permission/Read</EnumMember>
- </Annotation>
- </Property>
- <Property Name="Name" Type="Edm.String" Nullable="false" />
- <Property Name="IataCode" Type="Edm.String" Nullable="false">
- <Annotation Term="Org.OData.Core.V1.Immutable" Bool="true" />
- </Property>
- <Property Name="Location" Type="Microsoft.OData.SampleService.Models.TripPin.AirportLocation" Nullable="false" />
- </EntityType>
- <EntityType Name="PlanItem">
- <Key>
- <PropertyRef Name="PlanItemId" />
- </Key>
- <Property Name="PlanItemId" Type="Edm.Int32" Nullable="false">
- <Annotation Term="Org.OData.Core.V1.Permissions">
- <EnumMember>Org.OData.Core.V1.Permission/Read</EnumMember>
- </Annotation>
- </Property>
- <Property Name="ConfirmationCode" Type="Edm.String" />
- <Property Name="StartsAt" Type="Edm.DateTimeOffset" />
- <Property Name="EndsAt" Type="Edm.DateTimeOffset" />
- <Property Name="Duration" Type="Edm.Duration" />
- </EntityType>
- <EntityType Name="PublicTransportation" BaseType="Microsoft.OData.SampleService.Models.TripPin.PlanItem">
- <Property Name="SeatNumber" Type="Edm.String" />
- </EntityType>
- <EntityType Name="Flight" BaseType="Microsoft.OData.SampleService.Models.TripPin.PublicTransportation">
- <Property Name="FlightNumber" Type="Edm.String" Nullable="false" />
- <NavigationProperty Name="From" Type="Microsoft.OData.SampleService.Models.TripPin.Airport" Nullable="false" />
- <NavigationProperty Name="To" Type="Microsoft.OData.SampleService.Models.TripPin.Airport" Nullable="false" />
- <NavigationProperty Name="Airline" Type="Microsoft.OData.SampleService.Models.TripPin.Airline" Nullable="false" />
- </EntityType>
- <EntityType Name="Event" BaseType="Microsoft.OData.SampleService.Models.TripPin.PlanItem" OpenType="true">
- <Property Name="Description" Type="Edm.String" />
- <Property Name="OccursAt" Type="Microsoft.OData.SampleService.Models.TripPin.EventLocation" Nullable="false" />
- </EntityType>
- <EntityType Name="Trip">
- <Key>
- <PropertyRef Name="TripId" />
- </Key>
- <Property Name="TripId" Type="Edm.Int32" Nullable="false">
- <Annotation Term="Org.OData.Core.V1.Permissions">
- <EnumMember>Org.OData.Core.V1.Permission/Read</EnumMember>
- </Annotation>
- </Property>
- <Property Name="ShareId" Type="Edm.Guid" />
- <Property Name="Description" Type="Edm.String" />
- <Property Name="Name" Type="Edm.String" Nullable="false" />
- <Property Name="Budget" Type="Edm.Single" Nullable="false">
- <Annotation Term="Org.OData.Measures.V1.ISOCurrency" String="USD" />
- <Annotation Term="Org.OData.Measures.V1.Scale" Int="2" />
- </Property>
- <Property Name="StartsAt" Type="Edm.DateTimeOffset" Nullable="false" />
- <Property Name="EndsAt" Type="Edm.DateTimeOffset" Nullable="false" />
- <Property Name="Tags" Type="Collection(Edm.String)" Nullable="false" />
- <NavigationProperty Name="Photos" Type="Collection(Microsoft.OData.SampleService.Models.TripPin.Photo)" />
- <NavigationProperty Name="PlanItems" Type="Collection(Microsoft.OData.SampleService.Models.TripPin.PlanItem)" ContainsTarget="true" />
- </EntityType>
- <Function Name="GetFavoriteAirline" IsBound="true" EntitySetPath="person/Trips/PlanItems/Microsoft.OData.SampleService.Models.TripPin.Flight/Airline" IsComposable="true">
- <Parameter Name="person" Type="Microsoft.OData.SampleService.Models.TripPin.Person" Nullable="false" />
- <ReturnType Type="Microsoft.OData.SampleService.Models.TripPin.Airline" Nullable="false" />
- </Function>
- <Function Name="GetInvolvedPeople" IsBound="true" IsComposable="true">
- <Parameter Name="trip" Type="Microsoft.OData.SampleService.Models.TripPin.Trip" Nullable="false" />
- <ReturnType Type="Collection(Microsoft.OData.SampleService.Models.TripPin.Person)" Nullable="false" />
- </Function>
- <Function Name="GetFriendsTrips" IsBound="true" EntitySetPath="person/Friends/Trips" IsComposable="true">
- <Parameter Name="person" Type="Microsoft.OData.SampleService.Models.TripPin.Person" Nullable="false" />
- <Parameter Name="userName" Type="Edm.String" Nullable="false" />
- <ReturnType Type="Collection(Microsoft.OData.SampleService.Models.TripPin.Trip)" Nullable="false" />
- </Function>
- <Function Name="GetNearestAirport" IsComposable="true">
- <Parameter Name="lat" Type="Edm.Double" Nullable="false" />
- <Parameter Name="lon" Type="Edm.Double" Nullable="false" />
- <ReturnType Type="Microsoft.OData.SampleService.Models.TripPin.Airport" Nullable="false" />
- </Function>
- <Action Name="ResetDataSource" />
- <Action Name="ShareTrip" IsBound="true">
- <Parameter Name="person" Type="Microsoft.OData.SampleService.Models.TripPin.Person" Nullable="false" />
- <Parameter Name="userName" Type="Edm.String" Nullable="false" />
- <Parameter Name="tripId" Type="Edm.Int32" Nullable="false" />
- </Action>
- <EntityContainer Name="DefaultContainer">
- <EntitySet Name="Photos" EntityType="Microsoft.OData.SampleService.Models.TripPin.Photo">
- <Annotation Term="Org.OData.Core.V1.ResourcePath" String="Photos" />
- <Annotation Term="Org.OData.Capabilities.V1.SearchRestrictions">
- <Record>
- <PropertyValue Property="Searchable" Bool="true" />
- <PropertyValue Property="UnsupportedExpressions">
- <EnumMember>Org.OData.Capabilities.V1.SearchExpressions/none</EnumMember>
- </PropertyValue>
- </Record>
- </Annotation>
- <Annotation Term="Org.OData.Capabilities.V1.InsertRestrictions">
- <Record>
- <PropertyValue Property="Insertable" Bool="true" />
- <PropertyValue Property="NonInsertableNavigationProperties">
- <Collection />
- </PropertyValue>
- </Record>
- </Annotation>
- </EntitySet>
- <EntitySet Name="People" EntityType="Microsoft.OData.SampleService.Models.TripPin.Person">
- <NavigationPropertyBinding Path="Friends" Target="People" />
- <NavigationPropertyBinding Path="Microsoft.OData.SampleService.Models.TripPin.Flight/Airline" Target="Airlines" />
- <NavigationPropertyBinding Path="Microsoft.OData.SampleService.Models.TripPin.Flight/From" Target="Airports" />
- <NavigationPropertyBinding Path="Microsoft.OData.SampleService.Models.TripPin.Flight/To" Target="Airports" />
- <NavigationPropertyBinding Path="Photo" Target="Photos" />
- <NavigationPropertyBinding Path="Microsoft.OData.SampleService.Models.TripPin.Trip/Photos" Target="Photos" />
- <Annotation Term="Org.OData.Core.V1.OptimisticConcurrency">
- <Collection>
- <PropertyPath>Concurrency</PropertyPath>
- </Collection>
- </Annotation>
- <Annotation Term="Org.OData.Core.V1.ResourcePath" String="People" />
- <Annotation Term="Org.OData.Capabilities.V1.NavigationRestrictions">
- <Record>
- <PropertyValue Property="Navigability">
- <EnumMember>Org.OData.Capabilities.V1.NavigationType/None</EnumMember>
- </PropertyValue>
- <PropertyValue Property="RestrictedProperties">
- <Collection>
- <Record>
- <PropertyValue Property="NavigationProperty" NavigationPropertyPath="Friends" />
- <PropertyValue Property="Navigability">
- <EnumMember>Org.OData.Capabilities.V1.NavigationType/Recursive</EnumMember>
- </PropertyValue>
- </Record>
- </Collection>
- </PropertyValue>
- </Record>
- </Annotation>
- <Annotation Term="Org.OData.Capabilities.V1.SearchRestrictions">
- <Record>
- <PropertyValue Property="Searchable" Bool="true" />
- <PropertyValue Property="UnsupportedExpressions">
- <EnumMember>Org.OData.Capabilities.V1.SearchExpressions/none</EnumMember>
- </PropertyValue>
- </Record>
- </Annotation>
- <Annotation Term="Org.OData.Capabilities.V1.InsertRestrictions">
- <Record>
- <PropertyValue Property="Insertable" Bool="true" />
- <PropertyValue Property="NonInsertableNavigationProperties">
- <Collection>
- <NavigationPropertyPath>Trips</NavigationPropertyPath>
- <NavigationPropertyPath>Friends</NavigationPropertyPath>
- </Collection>
- </PropertyValue>
- </Record>
- </Annotation>
- </EntitySet>
- <EntitySet Name="Airlines" EntityType="Microsoft.OData.SampleService.Models.TripPin.Airline">
- <Annotation Term="Org.OData.Core.V1.ResourcePath" String="Airlines" />
- <Annotation Term="Org.OData.Capabilities.V1.SearchRestrictions">
- <Record>
- <PropertyValue Property="Searchable" Bool="true" />
- <PropertyValue Property="UnsupportedExpressions">
- <EnumMember>Org.OData.Capabilities.V1.SearchExpressions/none</EnumMember>
- </PropertyValue>
- </Record>
- </Annotation>
- <Annotation Term="Org.OData.Capabilities.V1.InsertRestrictions">
- <Record>
- <PropertyValue Property="Insertable" Bool="true" />
- <PropertyValue Property="NonInsertableNavigationProperties">
- <Collection />
- </PropertyValue>
- </Record>
- </Annotation>
- </EntitySet>
- <EntitySet Name="Airports" EntityType="Microsoft.OData.SampleService.Models.TripPin.Airport">
- <Annotation Term="Org.OData.Core.V1.ResourcePath" String="Airports" />
- <Annotation Term="Org.OData.Capabilities.V1.SearchRestrictions">
- <Record>
- <PropertyValue Property="Searchable" Bool="true" />
- <PropertyValue Property="UnsupportedExpressions">
- <EnumMember>Org.OData.Capabilities.V1.SearchExpressions/none</EnumMember>
- </PropertyValue>
- </Record>
- </Annotation>
- <Annotation Term="Org.OData.Capabilities.V1.InsertRestrictions">
- <Record>
- <PropertyValue Property="Insertable" Bool="false" />
- <PropertyValue Property="NonInsertableNavigationProperties">
- <Collection />
- </PropertyValue>
- </Record>
- </Annotation>
- <Annotation Term="Org.OData.Capabilities.V1.DeleteRestrictions">
- <Record>
- <PropertyValue Property="Deletable" Bool="false" />
- <PropertyValue Property="NonDeletableNavigationProperties">
- <Collection />
- </PropertyValue>
- </Record>
- </Annotation>
- </EntitySet>
- <Singleton Name="Me" Type="Microsoft.OData.SampleService.Models.TripPin.Person">
- <NavigationPropertyBinding Path="Friends" Target="People" />
- <NavigationPropertyBinding Path="Microsoft.OData.SampleService.Models.TripPin.Flight/Airline" Target="Airlines" />
- <NavigationPropertyBinding Path="Microsoft.OData.SampleService.Models.TripPin.Flight/From" Target="Airports" />
- <NavigationPropertyBinding Path="Microsoft.OData.SampleService.Models.TripPin.Flight/To" Target="Airports" />
- <NavigationPropertyBinding Path="Photo" Target="Photos" />
- <NavigationPropertyBinding Path="Microsoft.OData.SampleService.Models.TripPin.Trip/Photos" Target="Photos" />
- <Annotation Term="Org.OData.Core.V1.ResourcePath" String="Me" />
- </Singleton>
- <FunctionImport Name="GetNearestAirport" Function="Microsoft.OData.SampleService.Models.TripPin.GetNearestAirport" EntitySet="Airports" IncludeInServiceDocument="true">
- <Annotation Term="Org.OData.Core.V1.ResourcePath" String="Microsoft.OData.SampleService.Models.TripPin.GetNearestAirport" />
- </FunctionImport>
- <ActionImport Name="ResetDataSource" Action="Microsoft.OData.SampleService.Models.TripPin.ResetDataSource" />
- <Annotation Term="Org.OData.Core.V1.Description" String="TripPin service is a sample service for OData V4." />
- </EntityContainer>
- <Annotations Target="Microsoft.OData.SampleService.Models.TripPin.DefaultContainer">
- <Annotation Term="Org.OData.Core.V1.DereferenceableIDs" Bool="true" />
- <Annotation Term="Org.OData.Core.V1.ConventionalIDs" Bool="true" />
- <Annotation Term="Org.OData.Capabilities.V1.ConformanceLevel">
- <EnumMember>Org.OData.Capabilities.V1.ConformanceLevelType/Advanced</EnumMember>
- </Annotation>
- <Annotation Term="Org.OData.Capabilities.V1.SupportedFormats">
- <Collection>
- <String>application/json;odata.metadata=full;IEEE754Compatible=false;odata.streaming=true</String>
- <String>application/json;odata.metadata=minimal;IEEE754Compatible=false;odata.streaming=true</String>
- <String>application/json;odata.metadata=none;IEEE754Compatible=false;odata.streaming=true</String>
- </Collection>
- </Annotation>
- <Annotation Term="Org.OData.Capabilities.V1.AsynchronousRequestsSupported" Bool="true" />
- <Annotation Term="Org.OData.Capabilities.V1.BatchContinueOnErrorSupported" Bool="false" />
- <Annotation Term="Org.OData.Capabilities.V1.FilterFunctions">
- <Collection>
- <String>contains</String>
- <String>endswith</String>
- <String>startswith</String>
- <String>length</String>
- <String>indexof</String>
- <String>substring</String>
- <String>tolower</String>
- <String>toupper</String>
- <String>trim</String>
- <String>concat</String>
- <String>year</String>
- <String>month</String>
- <String>day</String>
- <String>hour</String>
- <String>minute</String>
- <String>second</String>
- <String>round</String>
- <String>floor</String>
- <String>ceiling</String>
- <String>cast</String>
- <String>isof</String>
- </Collection>
- </Annotation>
- </Annotations>
- </Schema>
- </edmx:DataServices>
+ <edmx:DataServices>
+ <Schema Namespace="Microsoft.OData.SampleService.Models.TripPin"
+ xmlns="http://docs.oasis-open.org/odata/ns/edm">
+ <EnumType Name="PersonGender">
+ <Member Name="Male" Value="0" />
+ <Member Name="Female" Value="1" />
+ <Member Name="Unknown" Value="2" />
+ </EnumType>
+ <ComplexType Name="City">
+ <Property Name="CountryRegion" Type="Edm.String" Nullable="false" />
+ <Property Name="Name" Type="Edm.String" Nullable="false" />
+ <Property Name="Region" Type="Edm.String" Nullable="false" />
+ </ComplexType>
+ <ComplexType Name="Location" OpenType="true">
+ <Property Name="Address" Type="Edm.String" Nullable="false" />
+ <Property Name="City"
+ Type="Microsoft.OData.SampleService.Models.TripPin.City" Nullable="false" />
+ </ComplexType>
+ <ComplexType Name="EventLocation"
+ BaseType="Microsoft.OData.SampleService.Models.TripPin.Location"
+ OpenType="true">
+ <Property Name="BuildingInfo" Type="Edm.String" />
+ </ComplexType>
+ <ComplexType Name="AirportLocation"
+ BaseType="Microsoft.OData.SampleService.Models.TripPin.Location"
+ OpenType="true">
+ <Property Name="Loc" Type="Edm.GeographyPoint" Nullable="false"
+ SRID="4326" />
+ </ComplexType>
+ <EntityType Name="Photo" HasStream="true">
+ <Key>
+ <PropertyRef Name="Id" />
+ </Key>
+ <Property Name="Id" Type="Edm.Int64" Nullable="false">
+ <Annotation Term="Org.OData.Core.V1.Permissions">
+ <EnumMember>Org.OData.Core.V1.Permission/Read</EnumMember>
+ </Annotation>
+ </Property>
+ <Property Name="Name" Type="Edm.String" />
+ <Annotation Term="Org.OData.Core.V1.AcceptableMediaTypes">
+ <Collection>
+ <String>image/jpeg</String>
+ </Collection>
+ </Annotation>
+ </EntityType>
+ <EntityType Name="Person" OpenType="true">
+ <Key>
+ <PropertyRef Name="UserName" />
+ </Key>
+ <Property Name="UserName" Type="Edm.String" Nullable="false">
+ <Annotation Term="Org.OData.Core.V1.Permissions">
+ <EnumMember>Org.OData.Core.V1.Permission/Read</EnumMember>
+ </Annotation>
+ </Property>
+ <Property Name="FirstName" Type="Edm.String" Nullable="true" />
+ <Property Name="LastName" Type="Edm.String" Nullable="false" />
+ <Property Name="Emails" Type="Collection(Edm.String)" />
+ <Property Name="AddressInfo"
+ Type="Collection(Microsoft.OData.SampleService.Models.TripPin.Location)" />
+ <Property Name="Gender"
+ Type="Microsoft.OData.SampleService.Models.TripPin.PersonGender" />
+ <Property Name="Concurrency" Type="Edm.Int64" Nullable="false">
+ <Annotation Term="Org.OData.Core.V1.Computed" Bool="true" />
+ </Property>
+ <NavigationProperty Name="Friends"
+ Type="Collection(Microsoft.OData.SampleService.Models.TripPin.Person)" />
+ <NavigationProperty Name="Trips"
+ Type="Collection(Microsoft.OData.SampleService.Models.TripPin.Trip)"
+ ContainsTarget="true" />
+ <NavigationProperty Name="Photo"
+ Type="Microsoft.OData.SampleService.Models.TripPin.Photo" />
+ </EntityType>
+ <EntityType Name="Airline">
+ <Key>
+ <PropertyRef Name="AirlineCode" />
+ </Key>
+ <Property Name="AirlineCode" Type="Edm.String" Nullable="false">
+ <Annotation Term="Org.OData.Core.V1.Permissions">
+ <EnumMember>Org.OData.Core.V1.Permission/Read</EnumMember>
+ </Annotation>
+ </Property>
+ <Property Name="Name" Type="Edm.String" Nullable="false" />
+ <Property Name="Picture" Type="Edm.Stream" Nullable="true" />
+ </EntityType>
+ <EntityType Name="Airport">
+ <Key>
+ <PropertyRef Name="IcaoCode" />
+ </Key>
+ <Property Name="IcaoCode" Type="Edm.String" Nullable="false">
+ <Annotation Term="Org.OData.Core.V1.Permissions">
+ <EnumMember>Org.OData.Core.V1.Permission/Read</EnumMember>
+ </Annotation>
+ </Property>
+ <Property Name="Name" Type="Edm.String" Nullable="false" />
+ <Property Name="IataCode" Type="Edm.String" Nullable="false">
+ <Annotation Term="Org.OData.Core.V1.Immutable" Bool="true" />
+ </Property>
+ <Property Name="Location"
+ Type="Microsoft.OData.SampleService.Models.TripPin.AirportLocation"
+ Nullable="false" />
+ </EntityType>
+ <EntityType Name="PlanItem">
+ <Key>
+ <PropertyRef Name="PlanItemId" />
+ </Key>
+ <Property Name="PlanItemId" Type="Edm.Int32" Nullable="false">
+ <Annotation Term="Org.OData.Core.V1.Permissions">
+ <EnumMember>Org.OData.Core.V1.Permission/Read</EnumMember>
+ </Annotation>
+ </Property>
+ <Property Name="ConfirmationCode" Type="Edm.String" />
+ <Property Name="StartsAt" Type="Edm.DateTimeOffset" />
+ <Property Name="EndsAt" Type="Edm.DateTimeOffset" />
+ <Property Name="Duration" Type="Edm.Duration" />
+ </EntityType>
+ <EntityType Name="PublicTransportation"
+ BaseType="Microsoft.OData.SampleService.Models.TripPin.PlanItem">
+ <Property Name="SeatNumber" Type="Edm.String" />
+ </EntityType>
+ <EntityType Name="Flight"
+ BaseType="Microsoft.OData.SampleService.Models.TripPin.PublicTransportation">
+ <Property Name="FlightNumber" Type="Edm.String" Nullable="false" />
+ <NavigationProperty Name="From"
+ Type="Microsoft.OData.SampleService.Models.TripPin.Airport"
+ Nullable="false" />
+ <NavigationProperty Name="To"
+ Type="Microsoft.OData.SampleService.Models.TripPin.Airport"
+ Nullable="false" />
+ <NavigationProperty Name="Airline"
+ Type="Microsoft.OData.SampleService.Models.TripPin.Airline"
+ Nullable="false" />
+ </EntityType>
+ <EntityType Name="Event"
+ BaseType="Microsoft.OData.SampleService.Models.TripPin.PlanItem"
+ OpenType="true">
+ <Property Name="Description" Type="Edm.String" />
+ <Property Name="OccursAt"
+ Type="Microsoft.OData.SampleService.Models.TripPin.EventLocation"
+ Nullable="false" />
+ </EntityType>
+ <EntityType Name="Trip">
+ <Key>
+ <PropertyRef Name="TripId" />
+ </Key>
+ <Property Name="TripId" Type="Edm.Int32" Nullable="false">
+ <Annotation Term="Org.OData.Core.V1.Permissions">
+ <EnumMember>Org.OData.Core.V1.Permission/Read</EnumMember>
+ </Annotation>
+ </Property>
+ <Property Name="ShareId" Type="Edm.Guid" />
+ <Property Name="Description" Type="Edm.String" />
+ <Property Name="Name" Type="Edm.String" Nullable="false" />
+ <Property Name="Budget" Type="Edm.Single" Nullable="false">
+ <Annotation Term="Org.OData.Measures.V1.ISOCurrency"
+ String="USD" />
+ <Annotation Term="Org.OData.Measures.V1.Scale" Int="2" />
+ </Property>
+ <Property Name="StartsAt" Type="Edm.DateTimeOffset"
+ Nullable="false" />
+ <Property Name="EndsAt" Type="Edm.DateTimeOffset" Nullable="false" />
+ <Property Name="Tags" Type="Collection(Edm.String)"
+ Nullable="false" />
+ <NavigationProperty Name="Photos"
+ Type="Collection(Microsoft.OData.SampleService.Models.TripPin.Photo)" />
+ <NavigationProperty Name="PlanItems"
+ Type="Collection(Microsoft.OData.SampleService.Models.TripPin.PlanItem)"
+ ContainsTarget="true" />
+ </EntityType>
+ <Function Name="GetFavoriteAirline" IsBound="true"
+ EntitySetPath="person/Trips/PlanItems/Microsoft.OData.SampleService.Models.TripPin.Flight/Airline"
+ IsComposable="true">
+ <Parameter Name="person"
+ Type="Microsoft.OData.SampleService.Models.TripPin.Person"
+ Nullable="false" />
+ <ReturnType Type="Microsoft.OData.SampleService.Models.TripPin.Airline"
+ Nullable="false" />
+ </Function>
+ <Function Name="GetInvolvedPeople" IsBound="true"
+ IsComposable="true">
+ <Parameter Name="trip"
+ Type="Microsoft.OData.SampleService.Models.TripPin.Trip" Nullable="false" />
+ <ReturnType
+ Type="Collection(Microsoft.OData.SampleService.Models.TripPin.Person)"
+ Nullable="false" />
+ </Function>
+ <Function Name="GetFriendsTrips" IsBound="true"
+ EntitySetPath="person/Friends/Trips" IsComposable="true">
+ <Parameter Name="person"
+ Type="Microsoft.OData.SampleService.Models.TripPin.Person"
+ Nullable="false" />
+ <Parameter Name="userName" Type="Edm.String" Nullable="false" />
+ <ReturnType
+ Type="Collection(Microsoft.OData.SampleService.Models.TripPin.Trip)"
+ Nullable="false" />
+ </Function>
+ <Function Name="GetNearestAirport" IsComposable="true">
+ <Parameter Name="lat" Type="Edm.Double" Nullable="false" />
+ <Parameter Name="lon" Type="Edm.Double" Nullable="false" />
+ <ReturnType Type="Microsoft.OData.SampleService.Models.TripPin.Airport"
+ Nullable="false" />
+ </Function>
+ <Action Name="ResetDataSource" />
+ <Action Name="ShareTrip" IsBound="true">
+ <Parameter Name="person"
+ Type="Microsoft.OData.SampleService.Models.TripPin.Person"
+ Nullable="false" />
+ <Parameter Name="userName" Type="Edm.String" Nullable="false" />
+ <Parameter Name="tripId" Type="Edm.Int32" Nullable="false" />
+ </Action>
+ <EntityContainer Name="DefaultContainer">
+ <EntitySet Name="Photos"
+ EntityType="Microsoft.OData.SampleService.Models.TripPin.Photo">
+ <Annotation Term="Org.OData.Core.V1.ResourcePath"
+ String="Photos" />
+ <Annotation Term="Org.OData.Capabilities.V1.SearchRestrictions">
+ <Record>
+ <PropertyValue Property="Searchable" Bool="true" />
+ <PropertyValue Property="UnsupportedExpressions">
+ <EnumMember>Org.OData.Capabilities.V1.SearchExpressions/none
+ </EnumMember>
+ </PropertyValue>
+ </Record>
+ </Annotation>
+ <Annotation Term="Org.OData.Capabilities.V1.InsertRestrictions">
+ <Record>
+ <PropertyValue Property="Insertable" Bool="true" />
+ <PropertyValue Property="NonInsertableNavigationProperties">
+ <Collection />
+ </PropertyValue>
+ </Record>
+ </Annotation>
+ </EntitySet>
+ <EntitySet Name="People"
+ EntityType="Microsoft.OData.SampleService.Models.TripPin.Person">
+ <NavigationPropertyBinding Path="Friends"
+ Target="People" />
+ <NavigationPropertyBinding
+ Path="Microsoft.OData.SampleService.Models.TripPin.Flight/Airline"
+ Target="Airlines" />
+ <NavigationPropertyBinding
+ Path="Microsoft.OData.SampleService.Models.TripPin.Flight/From"
+ Target="Airports" />
+ <NavigationPropertyBinding
+ Path="Microsoft.OData.SampleService.Models.TripPin.Flight/To"
+ Target="Airports" />
+ <NavigationPropertyBinding Path="Photo"
+ Target="Photos" />
+ <NavigationPropertyBinding
+ Path="Microsoft.OData.SampleService.Models.TripPin.Trip/Photos"
+ Target="Photos" />
+ <Annotation Term="Org.OData.Core.V1.OptimisticConcurrency">
+ <Collection>
+ <PropertyPath>Concurrency</PropertyPath>
+ </Collection>
+ </Annotation>
+ <Annotation Term="Org.OData.Core.V1.ResourcePath"
+ String="People" />
+ <Annotation Term="Org.OData.Capabilities.V1.NavigationRestrictions">
+ <Record>
+ <PropertyValue Property="Navigability">
+ <EnumMember>Org.OData.Capabilities.V1.NavigationType/None
+ </EnumMember>
+ </PropertyValue>
+ <PropertyValue Property="RestrictedProperties">
+ <Collection>
+ <Record>
+ <PropertyValue Property="NavigationProperty"
+ NavigationPropertyPath="Friends" />
+ <PropertyValue Property="Navigability">
+ <EnumMember>Org.OData.Capabilities.V1.NavigationType/Recursive
+ </EnumMember>
+ </PropertyValue>
+ </Record>
+ </Collection>
+ </PropertyValue>
+ </Record>
+ </Annotation>
+ <Annotation Term="Org.OData.Capabilities.V1.SearchRestrictions">
+ <Record>
+ <PropertyValue Property="Searchable" Bool="true" />
+ <PropertyValue Property="UnsupportedExpressions">
+ <EnumMember>Org.OData.Capabilities.V1.SearchExpressions/none
+ </EnumMember>
+ </PropertyValue>
+ </Record>
+ </Annotation>
+ <Annotation Term="Org.OData.Capabilities.V1.InsertRestrictions">
+ <Record>
+ <PropertyValue Property="Insertable" Bool="true" />
+ <PropertyValue Property="NonInsertableNavigationProperties">
+ <Collection>
+ <NavigationPropertyPath>Trips</NavigationPropertyPath>
+ <NavigationPropertyPath>Friends</NavigationPropertyPath>
+ </Collection>
+ </PropertyValue>
+ </Record>
+ </Annotation>
+ </EntitySet>
+ <EntitySet Name="Airlines"
+ EntityType="Microsoft.OData.SampleService.Models.TripPin.Airline">
+ <Annotation Term="Org.OData.Core.V1.ResourcePath"
+ String="Airlines" />
+ <Annotation Term="Org.OData.Capabilities.V1.SearchRestrictions">
+ <Record>
+ <PropertyValue Property="Searchable" Bool="true" />
+ <PropertyValue Property="UnsupportedExpressions">
+ <EnumMember>Org.OData.Capabilities.V1.SearchExpressions/none
+ </EnumMember>
+ </PropertyValue>
+ </Record>
+ </Annotation>
+ <Annotation Term="Org.OData.Capabilities.V1.InsertRestrictions">
+ <Record>
+ <PropertyValue Property="Insertable" Bool="true" />
+ <PropertyValue Property="NonInsertableNavigationProperties">
+ <Collection />
+ </PropertyValue>
+ </Record>
+ </Annotation>
+ </EntitySet>
+ <EntitySet Name="Airports"
+ EntityType="Microsoft.OData.SampleService.Models.TripPin.Airport">
+ <Annotation Term="Org.OData.Core.V1.ResourcePath"
+ String="Airports" />
+ <Annotation Term="Org.OData.Capabilities.V1.SearchRestrictions">
+ <Record>
+ <PropertyValue Property="Searchable" Bool="true" />
+ <PropertyValue Property="UnsupportedExpressions">
+ <EnumMember>Org.OData.Capabilities.V1.SearchExpressions/none
+ </EnumMember>
+ </PropertyValue>
+ </Record>
+ </Annotation>
+ <Annotation Term="Org.OData.Capabilities.V1.InsertRestrictions">
+ <Record>
+ <PropertyValue Property="Insertable" Bool="false" />
+ <PropertyValue Property="NonInsertableNavigationProperties">
+ <Collection />
+ </PropertyValue>
+ </Record>
+ </Annotation>
+ <Annotation Term="Org.OData.Capabilities.V1.DeleteRestrictions">
+ <Record>
+ <PropertyValue Property="Deletable" Bool="false" />
+ <PropertyValue Property="NonDeletableNavigationProperties">
+ <Collection />
+ </PropertyValue>
+ </Record>
+ </Annotation>
+ </EntitySet>
+ <Singleton Name="Me"
+ Type="Microsoft.OData.SampleService.Models.TripPin.Person">
+ <NavigationPropertyBinding Path="Friends"
+ Target="People" />
+ <NavigationPropertyBinding
+ Path="Microsoft.OData.SampleService.Models.TripPin.Flight/Airline"
+ Target="Airlines" />
+ <NavigationPropertyBinding
+ Path="Microsoft.OData.SampleService.Models.TripPin.Flight/From"
+ Target="Airports" />
+ <NavigationPropertyBinding
+ Path="Microsoft.OData.SampleService.Models.TripPin.Flight/To"
+ Target="Airports" />
+ <NavigationPropertyBinding Path="Photo"
+ Target="Photos" />
+ <NavigationPropertyBinding
+ Path="Microsoft.OData.SampleService.Models.TripPin.Trip/Photos"
+ Target="Photos" />
+ <Annotation Term="Org.OData.Core.V1.ResourcePath"
+ String="Me" />
+ </Singleton>
+ <FunctionImport Name="GetNearestAirport"
+ Function="Microsoft.OData.SampleService.Models.TripPin.GetNearestAirport"
+ EntitySet="Airports" IncludeInServiceDocument="true">
+ <Annotation Term="Org.OData.Core.V1.ResourcePath"
+ String="Microsoft.OData.SampleService.Models.TripPin.GetNearestAirport" />
+ </FunctionImport>
+ <ActionImport Name="ResetDataSource"
+ Action="Microsoft.OData.SampleService.Models.TripPin.ResetDataSource" />
+ <Annotation Term="Org.OData.Core.V1.Description"
+ String="TripPin service is a sample service for OData V4." />
+ </EntityContainer>
+ <Annotations
+ Target="Microsoft.OData.SampleService.Models.TripPin.DefaultContainer">
+ <Annotation Term="Org.OData.Core.V1.DereferenceableIDs"
+ Bool="true" />
+ <Annotation Term="Org.OData.Core.V1.ConventionalIDs"
+ Bool="true" />
+ <Annotation Term="Org.OData.Capabilities.V1.ConformanceLevel">
+ <EnumMember>Org.OData.Capabilities.V1.ConformanceLevelType/Advanced
+ </EnumMember>
+ </Annotation>
+ <Annotation Term="Org.OData.Capabilities.V1.SupportedFormats">
+ <Collection>
+ <String>application/json;odata.metadata=full;IEEE754Compatible=false;odata.streaming=true
+ </String>
+ <String>application/json;odata.metadata=minimal;IEEE754Compatible=false;odata.streaming=true
+ </String>
+ <String>application/json;odata.metadata=none;IEEE754Compatible=false;odata.streaming=true
+ </String>
+ </Collection>
+ </Annotation>
+ <Annotation
+ Term="Org.OData.Capabilities.V1.AsynchronousRequestsSupported"
+ Bool="true" />
+ <Annotation
+ Term="Org.OData.Capabilities.V1.BatchContinueOnErrorSupported"
+ Bool="false" />
+ <Annotation Term="Org.OData.Capabilities.V1.FilterFunctions">
+ <Collection>
+ <String>contains</String>
+ <String>endswith</String>
+ <String>startswith</String>
+ <String>length</String>
+ <String>indexof</String>
+ <String>substring</String>
+ <String>tolower</String>
+ <String>toupper</String>
+ <String>trim</String>
+ <String>concat</String>
+ <String>year</String>
+ <String>month</String>
+ <String>day</String>
+ <String>hour</String>
+ <String>minute</String>
+ <String>second</String>
+ <String>round</String>
+ <String>floor</String>
+ <String>ceiling</String>
+ <String>cast</String>
+ <String>isof</String>
+ </Collection>
+ </Annotation>
+ </Annotations>
+ <Term Name="IsURI" Type="Core.Tag" DefaultValue="true"
+ AppliesTo="Property">
+ <Annotation Term="Core.Description">
+ <String>
+ Properties and terms annotated with this term MUST contain a valid URI
+ </String>
+ </Annotation>
+ <Annotation Term="Core.RequiresType" String="Edm.String" />
+ </Term>
+ </Schema>
+ </edmx:DataServices>
</edmx:Edmx>
\ No newline at end of file
[09/22] olingo-odata4 git commit: [OLINGO-852] less warnings +
general clean-up
Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
deleted file mode 100644
index c287e5b..0000000
--- a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
+++ /dev/null
@@ -1,1947 +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.fit;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStreamWriter;
-import java.net.URI;
-import java.util.AbstractMap;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.ConcurrentModificationException;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.mail.Header;
-import javax.mail.internet.MimeBodyPart;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.GET;
-import javax.ws.rs.HeaderParam;
-import javax.ws.rs.NotFoundException;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedHashMap;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.cxf.jaxrs.client.WebClient;
-import org.apache.cxf.jaxrs.ext.multipart.Attachment;
-import org.apache.cxf.jaxrs.ext.multipart.Multipart;
-import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
-import org.apache.olingo.client.api.data.ResWrap;
-import org.apache.olingo.client.api.serialization.ODataDeserializer;
-import org.apache.olingo.client.api.serialization.ODataSerializer;
-import org.apache.olingo.client.core.serialization.AtomSerializer;
-import org.apache.olingo.client.core.serialization.JsonDeserializer;
-import org.apache.olingo.client.core.serialization.JsonSerializer;
-import org.apache.olingo.commons.api.data.ComplexValue;
-import org.apache.olingo.commons.api.data.Entity;
-import org.apache.olingo.commons.api.data.EntityCollection;
-import org.apache.olingo.commons.api.data.Link;
-import org.apache.olingo.commons.api.data.Property;
-import org.apache.olingo.commons.api.data.ValueType;
-import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
-import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
-import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
-import org.apache.olingo.commons.api.format.ContentType;
-import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
-import org.apache.olingo.fit.metadata.EntityType;
-import org.apache.olingo.fit.metadata.Metadata;
-import org.apache.olingo.fit.metadata.NavigationProperty;
-import org.apache.olingo.fit.methods.PATCH;
-import org.apache.olingo.fit.serializer.FITAtomDeserializer;
-import org.apache.olingo.fit.utils.AbstractUtilities;
-import org.apache.olingo.fit.utils.Accept;
-import org.apache.olingo.fit.utils.Commons;
-import org.apache.olingo.fit.utils.ConstantKey;
-import org.apache.olingo.fit.utils.Constants;
-import org.apache.olingo.fit.utils.FSManager;
-import org.apache.olingo.fit.utils.JSONUtilities;
-import org.apache.olingo.fit.utils.LinkInfo;
-import org.apache.olingo.fit.utils.XMLUtilities;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-public abstract class AbstractServices {
-
- /**
- * Logger.
- */
- protected static final Logger LOG = LoggerFactory.getLogger(AbstractServices.class);
-
- private static final Pattern REQUEST_PATTERN = Pattern.compile("(.*) (http://.*) HTTP/.*");
-
- private static final Pattern BATCH_REQUEST_REF_PATTERN = Pattern.compile("(.*) ([$]\\d+)(.*) HTTP/.*");
-
- private static final Pattern REF_PATTERN = Pattern.compile("([$]\\d+)");
-
- protected static final String BOUNDARY = "batch_243234_25424_ef_892u748";
-
- protected static final String MULTIPART_MIXED = "multipart/mixed";
-
- protected static final String APPLICATION_OCTET_STREAM = "application/octet-stream";
-
- protected final ODataServiceVersion version;
-
- protected final Metadata metadata;
-
- protected final ODataDeserializer atomDeserializer;
-
- protected final ODataDeserializer jsonDeserializer;
-
- protected final ODataSerializer atomSerializer;
-
- protected final ODataSerializer jsonSerializer;
-
- protected final XMLUtilities xml;
-
- protected final JSONUtilities json;
-
- public AbstractServices(final ODataServiceVersion version, final Metadata metadata) throws IOException {
- this.version = version;
- this.metadata = metadata;
-
- atomDeserializer = new FITAtomDeserializer();
- jsonDeserializer = new JsonDeserializer(true);
- atomSerializer = new AtomSerializer(true);
- jsonSerializer = new JsonSerializer(true, ContentType.JSON_FULL_METADATA);
-
- xml = new XMLUtilities(metadata);
- json = new JSONUtilities(metadata);
- }
-
- /**
- * Provide sample services.
- *
- * @param accept Accept header.
- * @return OData services.
- */
- @GET
- public Response getSevices(@HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept) {
- try {
- final Accept acceptType = Accept.parse(accept);
-
- if (acceptType == Accept.ATOM) {
- throw new UnsupportedMediaTypeException("Unsupported media type");
- }
-
- return xml.createResponse(
- null,
- FSManager.instance(version).readFile(Constants.get(ConstantKey.SERVICES), acceptType),
- null, acceptType);
- } catch (Exception e) {
- return xml.createFaultResponse(accept, e);
- }
- }
-
- /**
- * Provide sample getMetadata().
- *
- * @return getMetadata().
- */
- @GET
- @Path("/$metadata")
- @Produces(MediaType.APPLICATION_XML)
- public Response getMetadata() {
- return getMetadata(Constants.get(ConstantKey.METADATA));
- }
-
- protected Response getMetadata(final String filename) {
- try {
- return xml.createResponse(null, FSManager.instance(version).readRes(filename, Accept.XML), null, Accept.XML);
- } catch (Exception e) {
- return xml.createFaultResponse(Accept.XML.toString(), e);
- }
- }
-
- @POST
- @Path("/$batch")
- @Consumes(MULTIPART_MIXED)
- @Produces(APPLICATION_OCTET_STREAM + ";boundary=" + BOUNDARY)
- public Response batch(
- @HeaderParam("Authorization") @DefaultValue(StringUtils.EMPTY) final String authorization,
- @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
- final @Multipart MultipartBody attachment) {
- try {
- final boolean continueOnError = prefer.contains("odata.continue-on-error");
- return xml.createBatchResponse(
- exploreMultipart(attachment.getAllAttachments(), BOUNDARY, continueOnError));
- } catch (IOException e) {
- return xml.createFaultResponse(Accept.XML.toString(), e);
- }
- }
-
- // ----------------------------------------------
- // just for non nullable property test into PropertyTestITCase
- // ----------------------------------------------
- @PATCH
- @Path("/Driver('2')")
- public Response patchDriver() {
- return xml.createFaultResponse(Accept.JSON_FULLMETA.toString(), new Exception("Non nullable properties"));
- }
-
- @GET
- @Path("/StoredPIs(1000)")
- public Response getStoredPI(@Context final UriInfo uriInfo) {
- final Entity entity = new Entity();
- entity.setType("Microsoft.Test.OData.Services.ODataWCFService.StoredPI");
- final Property id = new Property();
- id.setType("Edm.Int32");
- id.setName("StoredPIID");
- id.setValue(ValueType.PRIMITIVE, 1000);
- entity.getProperties().add(id);
- final Link edit = new Link();
- edit.setHref(uriInfo.getRequestUri().toASCIIString());
- edit.setRel("edit");
- edit.setTitle("StoredPI");
- entity.setEditLink(edit);
-
- final ByteArrayOutputStream content = new ByteArrayOutputStream();
- final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING);
- try {
- jsonSerializer.write(writer, new ResWrap<Entity>((URI) null, null, entity));
- return xml.createResponse(new ByteArrayInputStream(content.toByteArray()), null, Accept.JSON_FULLMETA);
- } catch (Exception e) {
- LOG.error("While creating StoredPI", e);
- return xml.createFaultResponse(Accept.JSON_FULLMETA.toString(), e);
- }
- }
-
- @PATCH
- @Path("/StoredPIs(1000)")
- public Response patchStoredPI() {
- // just for non nullable property test into PropertyTestITCase
- return xml.createFaultResponse(Accept.JSON_FULLMETA.toString(), new Exception("Non nullable properties"));
- }
-
- // ----------------------------------------------
-
- protected Response bodyPartRequest(final MimeBodyPart body) throws Exception {
- return bodyPartRequest(body, Collections.<String, String> emptyMap());
- }
-
- protected Response bodyPartRequest(final MimeBodyPart body, final Map<String, String> references) throws Exception {
- @SuppressWarnings("unchecked")
- final Enumeration<Header> en = body.getAllHeaders();
-
- Header header = en.nextElement();
- final String request =
- header.getName() + (StringUtils.isNotBlank(header.getValue()) ? ":" + header.getValue() : "");
-
- final Matcher matcher = REQUEST_PATTERN.matcher(request);
- final Matcher matcherRef = BATCH_REQUEST_REF_PATTERN.matcher(request);
-
- final MultivaluedMap<String, String> headers = new MultivaluedHashMap<String, String>();
-
- while (en.hasMoreElements()) {
- header = en.nextElement();
- headers.putSingle(header.getName(), header.getValue());
- }
-
- final Response res;
- final String url;
- final String method;
-
- if (matcher.find()) {
- url = matcher.group(2);
- method = matcher.group(1);
- } else if (matcherRef.find()) {
- url = references.get(matcherRef.group(2)) + matcherRef.group(3);
- method = matcherRef.group(1);
- } else {
- url = null;
- method = null;
- }
-
- if (url == null) {
- res = null;
- } else {
- final WebClient client = WebClient.create(url, "odatajclient", "odatajclient", null);
- client.headers(headers);
-
- if ("DELETE".equals(method)) {
- res = client.delete();
- } else {
- final InputStream is = body.getDataHandler().getInputStream();
- String content = IOUtils.toString(is);
- IOUtils.closeQuietly(is);
-
- final Matcher refs = REF_PATTERN.matcher(content);
-
- while (refs.find()) {
- content = content.replace(refs.group(1), references.get(refs.group(1)));
- }
-
- if ("PATCH".equals(method) || "MERGE".equals(method)) {
- client.header("X-HTTP-METHOD", method);
- res = client.invoke("POST", IOUtils.toInputStream(content));
- } else {
- res = client.invoke(method, IOUtils.toInputStream(content));
- }
- }
-
- // When updating to CXF 3.0.1, uncomment the following line, see CXF-5865
- // client.close();
- }
-
- return res;
- }
-
- protected abstract InputStream exploreMultipart(
- final List<Attachment> attachments, final String boundary, final boolean continueOnError)
- throws IOException;
-
- protected void addItemIntro(final ByteArrayOutputStream bos) throws IOException {
- addItemIntro(bos, null);
- }
-
- protected void addItemIntro(final ByteArrayOutputStream bos, final String contentId) throws IOException {
- bos.write("Content-Type: application/http".getBytes());
- bos.write(Constants.CRLF);
- bos.write("Content-Transfer-Encoding: binary".getBytes());
- bos.write(Constants.CRLF);
-
- if (StringUtils.isNotBlank(contentId)) {
- bos.write(("Content-ID: " + contentId).getBytes());
- bos.write(Constants.CRLF);
- }
-
- bos.write(Constants.CRLF);
- }
-
- protected void addChangesetItemIntro(
- final ByteArrayOutputStream bos, final String contentId, final String cboundary) throws IOException {
- bos.write(("--" + cboundary).getBytes());
- bos.write(Constants.CRLF);
- bos.write(("Content-ID: " + contentId).getBytes());
- bos.write(Constants.CRLF);
- addItemIntro(bos);
- }
-
- protected void addSingleBatchResponse(
- final Response response, final ByteArrayOutputStream bos) throws IOException {
- addSingleBatchResponse(response, null, bos);
- }
-
- protected void addSingleBatchResponse(
- final Response response, final String contentId, final ByteArrayOutputStream bos) throws IOException {
- bos.write("HTTP/1.1 ".getBytes());
- bos.write(String.valueOf(response.getStatusInfo().getStatusCode()).getBytes());
- bos.write(" ".getBytes());
- bos.write(response.getStatusInfo().getReasonPhrase().getBytes());
- bos.write(Constants.CRLF);
-
- for (Map.Entry<String, List<Object>> header : response.getHeaders().entrySet()) {
- final StringBuilder builder = new StringBuilder();
- for (Object value : header.getValue()) {
- if (builder.length() > 0) {
- builder.append(", ");
- }
- builder.append(value.toString());
- }
- builder.insert(0, ": ").insert(0, header.getKey());
- bos.write(builder.toString().getBytes());
- bos.write(Constants.CRLF);
- }
-
- if (StringUtils.isNotBlank(contentId)) {
- bos.write(("Content-ID: " + contentId).getBytes());
- bos.write(Constants.CRLF);
- }
-
- bos.write(Constants.CRLF);
-
- final Object entity = response.getEntity();
- if (entity != null) {
- bos.write(IOUtils.toByteArray((InputStream) entity));
- bos.write(Constants.CRLF);
- }
-
- bos.write(Constants.CRLF);
- }
-
- protected void addErrorBatchResponse(final Exception e, final ByteArrayOutputStream bos)
- throws IOException {
- addErrorBatchResponse(e, null, bos);
- }
-
- protected void addErrorBatchResponse(final Exception e, final String contentId, final ByteArrayOutputStream bos)
- throws IOException {
- addSingleBatchResponse(xml.createFaultResponse(Accept.XML.toString(), e), contentId, bos);
- }
-
- @PATCH
- @Path("/{entitySetName}({entityId})")
- @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
- @Consumes({ MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
- public Response patchEntity(
- @Context final UriInfo uriInfo,
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
- @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
- @HeaderParam("If-Match") @DefaultValue(StringUtils.EMPTY) final String ifMatch,
- @PathParam("entitySetName") final String entitySetName,
- @PathParam("entityId") final String entityId,
- final String changes) {
-
- try {
- final Accept acceptType = Accept.parse(accept);
-
- if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
- throw new UnsupportedMediaTypeException("Unsupported media type");
- }
-
- final Map.Entry<String, InputStream> entityInfo = xml.readEntity(entitySetName, entityId, Accept.ATOM);
-
- final String etag = Commons.getETag(entityInfo.getKey());
- if (StringUtils.isNotBlank(ifMatch) && !ifMatch.equals(etag)) {
- throw new ConcurrentModificationException("Concurrent modification");
- }
-
- final Accept contentTypeValue = Accept.parse(contentType);
-
- final Entity entryChanges;
-
- if (contentTypeValue == Accept.XML || contentTypeValue == Accept.TEXT) {
- throw new UnsupportedMediaTypeException("Unsupported media type");
- } else if (contentTypeValue == Accept.ATOM) {
- entryChanges = atomDeserializer.toEntity(
- IOUtils.toInputStream(changes, Constants.ENCODING)).getPayload();
- } else {
- final ResWrap<Entity> jcont = jsonDeserializer.toEntity(IOUtils.toInputStream(changes, Constants.ENCODING));
- entryChanges = jcont.getPayload();
- }
-
- final ResWrap<Entity> container = atomDeserializer.toEntity(entityInfo.getValue());
-
- for (Property property : entryChanges.getProperties()) {
- final Property _property = container.getPayload().getProperty(property.getName());
- if (_property == null) {
- container.getPayload().getProperties().add(property);
- } else {
- _property.setValue(property.getValueType(), property.getValue());
- }
- }
-
- for (Link link : entryChanges.getNavigationLinks()) {
- container.getPayload().getNavigationLinks().add(link);
- }
-
- final ByteArrayOutputStream content = new ByteArrayOutputStream();
- final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING);
- atomSerializer.write(writer, container);
- writer.flush();
- writer.close();
-
- final InputStream res = xml.addOrReplaceEntity(
- entityId, entitySetName, new ByteArrayInputStream(content.toByteArray()), container.getPayload());
-
- final ResWrap<Entity> cres = atomDeserializer.toEntity(res);
-
- normalizeAtomEntry(cres.getPayload(), entitySetName, entityId);
-
- final String path = Commons.getEntityBasePath(entitySetName, entityId);
- FSManager.instance(version).putInMemory(
- cres, path + File.separatorChar + Constants.get(ConstantKey.ENTITY));
-
- final Response response;
- if ("return-content".equalsIgnoreCase(prefer)) {
- response = xml.createResponse(
- uriInfo.getRequestUri().toASCIIString(),
- xml.readEntity(entitySetName, entityId, acceptType).getValue(),
- null, acceptType, Response.Status.OK);
- } else {
- res.close();
- response = xml.createResponse(
- uriInfo.getRequestUri().toASCIIString(),
- null,
- null,
- acceptType, Response.Status.NO_CONTENT);
- }
-
- if (StringUtils.isNotBlank(prefer)) {
- response.getHeaders().put("Preference-Applied", Collections.<Object> singletonList(prefer));
- }
-
- return response;
- } catch (Exception e) {
- return xml.createFaultResponse(accept, e);
- }
- }
-
- @PUT
- @Path("/{entitySetName}({entityId})")
- @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
- @Consumes({ MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
- public Response replaceEntity(
- @Context final UriInfo uriInfo,
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
- @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
- @PathParam("entitySetName") final String entitySetName,
- @PathParam("entityId") final String entityId,
- final String entity) {
-
- try {
- final Accept acceptType = Accept.parse(accept);
-
- if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
- throw new UnsupportedMediaTypeException("Unsupported media type");
- }
-
- final InputStream res = getUtilities(acceptType).addOrReplaceEntity(entityId, entitySetName,
- IOUtils.toInputStream(entity, Constants.ENCODING),
- xml.readEntity(acceptType, IOUtils.toInputStream(entity, Constants.ENCODING)));
-
- final ResWrap<Entity> cres;
- if (acceptType == Accept.ATOM) {
- cres = atomDeserializer.toEntity(res);
- } else {
- cres = jsonDeserializer.toEntity(res);
- }
-
- final String path = Commons.getEntityBasePath(entitySetName, entityId);
- FSManager.instance(version).putInMemory(
- cres, path + File.separatorChar + Constants.get(ConstantKey.ENTITY));
-
- final Response response;
- if ("return-content".equalsIgnoreCase(prefer)) {
- response = xml.createResponse(
- uriInfo.getRequestUri().toASCIIString(),
- xml.readEntity(entitySetName, entityId, acceptType).getValue(),
- null,
- acceptType,
- Response.Status.OK);
- } else {
- res.close();
- response = xml.createResponse(
- uriInfo.getRequestUri().toASCIIString(),
- null,
- null,
- acceptType,
- Response.Status.NO_CONTENT);
- }
-
- if (StringUtils.isNotBlank(prefer)) {
- response.getHeaders().put("Preference-Applied", Collections.<Object> singletonList(prefer));
- }
-
- return response;
- } catch (Exception e) {
- return xml.createFaultResponse(accept, e);
- }
- }
-
- @POST
- @Path("/{entitySetName}")
- @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
- @Consumes({ MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM })
- public Response postNewEntity(
- @Context final UriInfo uriInfo,
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
- @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
- @PathParam("entitySetName") final String entitySetName,
- final String entity) {
-
- try {
- final Accept acceptType = Accept.parse(accept);
- if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
- throw new UnsupportedMediaTypeException("Unsupported media type");
- }
-
- final ResWrap<Entity> container;
-
- final org.apache.olingo.fit.metadata.EntitySet entitySet = metadata.getEntitySet(entitySetName);
-
- final Entity entry;
- final String entityKey;
- if (xml.isMediaContent(entitySetName)) {
- entry = new Entity();
- entry.setMediaContentType(ContentType.APPLICATION_OCTET_STREAM.toContentTypeString());
- entry.setType(entitySet.getType());
-
- entityKey = xml.getDefaultEntryKey(entitySetName, entry);
-
- xml.addMediaEntityValue(entitySetName, entityKey, IOUtils.toInputStream(entity, Constants.ENCODING));
-
- final Pair<String, EdmPrimitiveTypeKind> id = Commons.getMediaContent().get(entitySetName);
- if (id != null) {
- final Property prop = new Property();
- prop.setName(id.getKey());
- prop.setType(id.getValue().toString());
- prop.setValue(ValueType.PRIMITIVE,
- id.getValue() == EdmPrimitiveTypeKind.Int32
- ? Integer.parseInt(entityKey)
- : id.getValue() == EdmPrimitiveTypeKind.Guid
- ? UUID.fromString(entityKey)
- : entityKey);
- entry.getProperties().add(prop);
- }
-
- final Link editLink = new Link();
- editLink.setHref(Commons.getEntityURI(entitySetName, entityKey));
- editLink.setRel("edit");
- editLink.setTitle(entitySetName);
- entry.setEditLink(editLink);
-
- entry.setMediaContentSource(URI.create(editLink.getHref() + "/$value"));
-
- container = new ResWrap<Entity>((URI) null, null, entry);
- } else {
- final Accept contentTypeValue = Accept.parse(contentType);
- if (Accept.ATOM == contentTypeValue) {
- container = atomDeserializer.toEntity(IOUtils.toInputStream(entity, Constants.ENCODING));
- } else {
- container = jsonDeserializer.toEntity(IOUtils.toInputStream(entity, Constants.ENCODING));
- }
- entry = container.getPayload();
- updateInlineEntities(entry);
-
- entityKey = xml.getDefaultEntryKey(entitySetName, entry);
- }
-
- normalizeAtomEntry(entry, entitySetName, entityKey);
-
- final ByteArrayOutputStream content = new ByteArrayOutputStream();
- final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING);
- atomSerializer.write(writer, container);
- writer.flush();
- writer.close();
-
- final InputStream serialization =
- xml.addOrReplaceEntity(entityKey, entitySetName, new ByteArrayInputStream(content.toByteArray()), entry);
-
- ResWrap<Entity> result = atomDeserializer.toEntity(serialization);
- result = new ResWrap<Entity>(
- URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX)
- + entitySetName + Constants.get(ConstantKey.ODATA_METADATA_ENTITY_SUFFIX)),
- null, result.getPayload());
-
- final String path = Commons.getEntityBasePath(entitySetName, entityKey);
- FSManager.instance(version).putInMemory(result, path + Constants.get(ConstantKey.ENTITY));
-
- final String location;
-
- if ((this instanceof KeyAsSegment)) {
- location = uriInfo.getRequestUri().toASCIIString() + "/" + entityKey;
-
- final Link editLink = new Link();
- editLink.setRel("edit");
- editLink.setTitle(entitySetName);
- editLink.setHref(location);
-
- result.getPayload().setEditLink(editLink);
- } else {
- location = uriInfo.getRequestUri().toASCIIString() + "(" + entityKey + ")";
- }
-
- final Response response;
- if ("return-no-content".equalsIgnoreCase(prefer)) {
- response = xml.createResponse(
- location,
- null,
- null,
- acceptType,
- Response.Status.NO_CONTENT);
- } else {
- response = xml.createResponse(
- location,
- xml.writeEntity(acceptType, result),
- null,
- acceptType,
- Response.Status.CREATED);
- }
-
- if (StringUtils.isNotBlank(prefer)) {
- response.getHeaders().put("Preference-Applied", Collections.<Object> singletonList(prefer));
- }
-
- return response;
- } catch (Exception e) {
- LOG.error("While creating new entity", e);
- return xml.createFaultResponse(accept, e);
- }
- }
-
- @POST
- @Path("/Person({entityId})/{type:.*}/Sack")
- public Response actionSack(
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @PathParam("entityId") final String entityId,
- @PathParam("type") final String type,
- @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
-
- final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
-
- if (utils.getKey() == Accept.XML || utils.getKey() == Accept.TEXT) {
- throw new UnsupportedMediaTypeException("Unsupported media type");
- }
-
- try {
- final Map.Entry<String, InputStream> entityInfo = xml.readEntity("Person", entityId, Accept.ATOM);
-
- final InputStream entity = entityInfo.getValue();
- final ResWrap<Entity> container = atomDeserializer.toEntity(entity);
-
- container.getPayload().getProperty("Salary").setValue(ValueType.PRIMITIVE, 0);
- container.getPayload().getProperty("Title").setValue(ValueType.PRIMITIVE, "[Sacked]");
-
- final FSManager fsManager = FSManager.instance(version);
- fsManager.putInMemory(xml.writeEntity(Accept.ATOM, container),
- fsManager.getAbsolutePath(Commons.getEntityBasePath("Person", entityId) + Constants.get(
- ConstantKey.ENTITY), Accept.ATOM));
-
- return utils.getValue().createResponse(null, null, null, utils.getKey(), Response.Status.NO_CONTENT);
- } catch (Exception e) {
- return xml.createFaultResponse(accept, e);
- }
- }
-
- @POST
- @Path("/Person/{type:.*}/IncreaseSalaries")
- public Response actionIncreaseSalaries(
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @PathParam("type") final String type,
- @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
- final String body) {
-
- final String name = "Person";
- try {
- final Accept acceptType = Accept.parse(accept);
- if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
- throw new UnsupportedMediaTypeException("Unsupported media type");
- }
-
- final JsonNode tree = new ObjectMapper().readTree(body);
- if (!tree.has("n")) {
- throw new Exception("Missing parameter: n");
- }
- final int n = tree.get("n").asInt();
-
- final StringBuilder path = new StringBuilder(name).
- append(File.separatorChar).append(type).
- append(File.separatorChar);
-
- path.append(metadata.getEntitySet(name).isSingleton()
- ? Constants.get(ConstantKey.ENTITY)
- : Constants.get(ConstantKey.FEED));
-
- final InputStream feed = FSManager.instance(version).readFile(path.toString(), acceptType);
-
- final ByteArrayOutputStream copy = new ByteArrayOutputStream();
- IOUtils.copy(feed, copy);
- IOUtils.closeQuietly(feed);
-
- String newContent = new String(copy.toByteArray(), "UTF-8");
- final Pattern salary = Pattern.compile(acceptType == Accept.ATOM
- ? "\\<d:Salary m:type=\"Edm.Int32\"\\>(-?\\d+)\\</d:Salary\\>"
- : "\"Salary\":(-?\\d+),");
- final Matcher salaryMatcher = salary.matcher(newContent);
- while (salaryMatcher.find()) {
- final Long newSalary = Long.valueOf(salaryMatcher.group(1)) + n;
- newContent = newContent.
- replaceAll("\"Salary\":" + salaryMatcher.group(1) + ",",
- "\"Salary\":" + newSalary + ",").
- replaceAll("\\<d:Salary m:type=\"Edm.Int32\"\\>" + salaryMatcher.group(1) + "</d:Salary\\>",
- "<d:Salary m:type=\"Edm.Int32\">" + newSalary + "</d:Salary>");
- }
-
- FSManager.instance(version).putInMemory(IOUtils.toInputStream(newContent, Constants.ENCODING),
- FSManager.instance(version).getAbsolutePath(path.toString(), acceptType));
-
- return xml.createResponse(null, null, null, acceptType, Response.Status.NO_CONTENT);
- } catch (Exception e) {
- return xml.createFaultResponse(accept, e);
- }
- }
-
- @POST
- @Path("/Product({entityId})/ChangeProductDimensions")
- public Response actionChangeProductDimensions(
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @PathParam("entityId") final String entityId,
- @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
- final String argument) {
-
- final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
-
- if (utils.getKey() == Accept.XML || utils.getKey() == Accept.TEXT) {
- throw new UnsupportedMediaTypeException("Unsupported media type");
- }
-
- try {
- final Map.Entry<String, InputStream> entityInfo = xml.readEntity("Product", entityId, Accept.ATOM);
-
- final InputStream entity = entityInfo.getValue();
- final ResWrap<Entity> container = atomDeserializer.toEntity(entity);
-
- final Entity param = xml.readEntity(utils.getKey(), IOUtils.toInputStream(argument, Constants.ENCODING));
-
- final Property property = param.getProperty("dimensions");
- container.getPayload().getProperty("Dimensions").setValue(property.getValueType(), property.getValue());
-
- final FSManager fsManager = FSManager.instance(version);
- fsManager.putInMemory(xml.writeEntity(Accept.ATOM, container),
- fsManager.getAbsolutePath(Commons.getEntityBasePath("Product", entityId) + Constants.get(
- ConstantKey.ENTITY), Accept.ATOM));
-
- return utils.getValue().createResponse(null, null, null, utils.getKey(), Response.Status.NO_CONTENT);
- } catch (Exception e) {
- return xml.createFaultResponse(accept, e);
- }
- }
-
- @POST
- @Path("/ComputerDetail({entityId})/ResetComputerDetailsSpecifications")
- public Response actionResetComputerDetailsSpecifications(
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @PathParam("entityId") final String entityId,
- @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
- final String argument) {
-
- final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
-
- if (utils.getKey() == Accept.XML || utils.getKey() == Accept.TEXT) {
- throw new UnsupportedMediaTypeException("Unsupported media type");
- }
-
- try {
- final Map.Entry<String, InputStream> entityInfo = xml.readEntity("ComputerDetail", entityId, Accept.ATOM);
-
- final InputStream entity = entityInfo.getValue();
- final ResWrap<Entity> container = atomDeserializer.toEntity(entity);
-
- final Entity param = xml.readEntity(utils.getKey(), IOUtils.toInputStream(argument, Constants.ENCODING));
-
- Property property = param.getProperty("specifications");
- container.getPayload().getProperty("SpecificationsBag").setValue(property.getValueType(), property.getValue());
- property = param.getProperty("purchaseTime");
- container.getPayload().getProperty("PurchaseDate").setValue(property.getValueType(), property.getValue());
-
- final FSManager fsManager = FSManager.instance(version);
- fsManager.putInMemory(xml.writeEntity(Accept.ATOM, container),
- fsManager.getAbsolutePath(Commons.getEntityBasePath("ComputerDetail", entityId) + Constants.get(
- ConstantKey.ENTITY), Accept.ATOM));
-
- return utils.getValue().createResponse(null, null, null, utils.getKey(), Response.Status.NO_CONTENT);
- } catch (Exception e) {
- return xml.createFaultResponse(accept, e);
- }
- }
-
- /**
- * Retrieve entities from the given entity set and the given type.
- *
- * @param accept Accept header.
- * @param name entity set.
- * @param type entity type.
- * @return entity set.
- */
- @GET
- @Path("/{name}/{type:[a-zA-Z].*}")
- public Response getEntitySet(
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @PathParam("name") final String name,
- @PathParam("type") final String type) {
-
- try {
- final Accept acceptType = Accept.parse(accept);
- if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
- throw new UnsupportedMediaTypeException("Unsupported media type");
- }
-
- final String basePath = name + File.separatorChar;
- final StringBuilder path = new StringBuilder(name).
- append(File.separatorChar).append(type).
- append(File.separatorChar);
-
- path.append(metadata.getEntitySet(name).isSingleton()
- ? Constants.get(ConstantKey.ENTITY)
- : Constants.get(ConstantKey.FEED));
-
- final InputStream feed = FSManager.instance(version).readFile(path.toString(), acceptType);
- return xml.createResponse(null, feed, Commons.getETag(basePath), acceptType);
- } catch (Exception e) {
- return xml.createFaultResponse(accept, e);
- }
- }
-
- @GET
- @Path("/{name}/{type:[a-zA-Z].*}")
- public Response getEntitySet(@Context final UriInfo uriInfo,
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @PathParam("name") final String name,
- @QueryParam("$top") @DefaultValue(StringUtils.EMPTY) final String top,
- @QueryParam("$skip") @DefaultValue(StringUtils.EMPTY) final String skip,
- @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
- @QueryParam("$count") @DefaultValue(StringUtils.EMPTY) final String count,
- @QueryParam("$filter") @DefaultValue(StringUtils.EMPTY) final String filter,
- @QueryParam("$orderby") @DefaultValue(StringUtils.EMPTY) final String orderby,
- @QueryParam("$skiptoken") @DefaultValue(StringUtils.EMPTY) final String skiptoken,
- @PathParam("type") final String type) {
-
- try {
- final Accept acceptType;
- if (StringUtils.isNotBlank(format)) {
- acceptType = Accept.valueOf(format.toUpperCase());
- } else {
- acceptType = Accept.parse(accept);
- }
-
- final String location = uriInfo.getRequestUri().toASCIIString();
- try {
- // search for function ...
- final InputStream func = FSManager.instance(version).readFile(name, acceptType);
- return xml.createResponse(location, func, null, acceptType);
- } catch (NotFoundException e) {
- if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
- throw new UnsupportedMediaTypeException("Unsupported media type");
- }
-
- // search for entitySet ...
- final String basePath = name + File.separatorChar;
-
- final StringBuilder builder = new StringBuilder();
- builder.append(basePath);
-
- if (type != null) {
- builder.append(type).append(File.separatorChar);
- }
-
- if (StringUtils.isNotBlank(orderby)) {
- builder.append(Constants.get(ConstantKey.ORDERBY)).append(File.separatorChar).
- append(orderby).append(File.separatorChar);
- }
-
- if (StringUtils.isNotBlank(filter)) {
- builder.append(Constants.get(ConstantKey.FILTER)).append(File.separatorChar).
- append(filter.replaceAll("/", "."));
- } else if (StringUtils.isNotBlank(skiptoken)) {
- builder.append(Constants.get(ConstantKey.SKIP_TOKEN)).append(File.separatorChar).
- append(skiptoken);
- } else {
- builder.append(metadata.getEntitySet(name).isSingleton()
- ? Constants.get(ConstantKey.ENTITY)
- : Constants.get(ConstantKey.FEED));
- }
-
- final InputStream feed = FSManager.instance(version).readFile(builder.toString(), Accept.ATOM);
-
- final ResWrap<EntityCollection> container = atomDeserializer.toEntitySet(feed);
-
- setInlineCount(container.getPayload(), count);
-
- final ByteArrayOutputStream content = new ByteArrayOutputStream();
- final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING);
-
- // -----------------------------------------------
- // Evaluate $skip and $top
- // -----------------------------------------------
- List<Entity> entries = new ArrayList<Entity>(container.getPayload().getEntities());
-
- if (StringUtils.isNotBlank(skip)) {
- entries = entries.subList(Integer.valueOf(skip), entries.size());
- }
-
- if (StringUtils.isNotBlank(top)) {
- entries = entries.subList(0, Integer.valueOf(top));
- }
-
- container.getPayload().getEntities().clear();
- container.getPayload().getEntities().addAll(entries);
- // -----------------------------------------------
-
- if (acceptType == Accept.ATOM) {
- atomSerializer.write(writer, container);
- } else {
- jsonSerializer.write(writer, container);
- }
- writer.flush();
- writer.close();
-
- return xml.createResponse(
- location,
- new ByteArrayInputStream(content.toByteArray()),
- Commons.getETag(basePath),
- acceptType);
- }
- } catch (Exception e) {
- return xml.createFaultResponse(accept, e);
- }
- }
-
- /**
- * Retrieve entity set or function execution sample.
- *
- * @param accept Accept header.
- * @param name entity set or function name.
- * @param format format query option.
- * @param count count query option.
- * @param filter filter query option.
- * @param orderby orderby query option.
- * @param skiptoken skiptoken query option.
- * @return entity set or function result.
- */
- @GET
- @Path("/{name}")
- public Response getEntitySet(
- @Context final UriInfo uriInfo,
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @PathParam("name") final String name,
- @QueryParam("$top") @DefaultValue(StringUtils.EMPTY) final String top,
- @QueryParam("$skip") @DefaultValue(StringUtils.EMPTY) final String skip,
- @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
- @QueryParam("$count") @DefaultValue(StringUtils.EMPTY) final String count,
- @QueryParam("$filter") @DefaultValue(StringUtils.EMPTY) final String filter,
- @QueryParam("$orderby") @DefaultValue(StringUtils.EMPTY) final String orderby,
- @QueryParam("$skiptoken") @DefaultValue(StringUtils.EMPTY) final String skiptoken) {
-
- return getEntitySet(uriInfo, accept, name, top, skip, format, count, filter, orderby, skiptoken, null);
- }
-
- protected abstract void setInlineCount(final EntityCollection feed, final String count);
-
- @GET
- @Path("/Person({entityId})")
- public Response getPerson(
- @Context final UriInfo uriInfo,
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @PathParam("entityId") final String entityId,
- @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
-
- final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
-
- final Response internal = getEntityInternal(
- uriInfo.getRequestUri().toASCIIString(), accept, "Person", entityId, format, null, null);
- if (internal.getStatus() == 200) {
- InputStream entity = (InputStream) internal.getEntity();
- try {
- if (utils.getKey() == Accept.JSON_FULLMETA || utils.getKey() == Accept.ATOM) {
- entity = utils.getValue().addOperation(entity, "Sack", "#DefaultContainer.Sack",
- uriInfo.getAbsolutePath().toASCIIString()
- + "/Microsoft.Test.OData.Services.AstoriaDefaultService.SpecialEmployee/Sack");
- }
-
- return utils.getValue().createResponse(
- uriInfo.getRequestUri().toASCIIString(),
- entity,
- internal.getHeaderString("ETag"),
- utils.getKey());
- } catch (Exception e) {
- LOG.error("Error retrieving entity", e);
- return xml.createFaultResponse(accept, e);
- }
- } else {
- return internal;
- }
- }
-
- @GET
- @Path("/Product({entityId})")
- public Response getProduct(
- @Context final UriInfo uriInfo,
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @PathParam("entityId") final String entityId,
- @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
-
- final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
-
- final Response internal = getEntityInternal(
- uriInfo.getRequestUri().toASCIIString(), accept, "Product", entityId, format, null, null);
- if (internal.getStatus() == 200) {
- InputStream entity = (InputStream) internal.getEntity();
- try {
- if (utils.getKey() == Accept.JSON_FULLMETA || utils.getKey() == Accept.ATOM) {
- entity = utils.getValue().addOperation(entity,
- "ChangeProductDimensions", "#DefaultContainer.ChangeProductDimensions",
- uriInfo.getAbsolutePath().toASCIIString() + "/ChangeProductDimensions");
- }
-
- return utils.getValue().createResponse(
- uriInfo.getRequestUri().toASCIIString(),
- entity,
- internal.getHeaderString("ETag"),
- utils.getKey());
- } catch (Exception e) {
- LOG.error("Error retrieving entity", e);
- return xml.createFaultResponse(accept, e);
- }
- } else {
- return internal;
- }
- }
-
- @GET
- @Path("/ComputerDetail({entityId})")
- public Response getComputerDetail(
- @Context final UriInfo uriInfo,
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @PathParam("entityId") final String entityId,
- @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
-
- final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
-
- final Response internal = getEntityInternal(
- uriInfo.getRequestUri().toASCIIString(), accept, "ComputerDetail", entityId, format, null, null);
- if (internal.getStatus() == 200) {
- InputStream entity = (InputStream) internal.getEntity();
- try {
- if (utils.getKey() == Accept.JSON_FULLMETA || utils.getKey() == Accept.ATOM) {
- entity = utils.getValue().addOperation(entity,
- "ResetComputerDetailsSpecifications", "#DefaultContainer.ResetComputerDetailsSpecifications",
- uriInfo.getAbsolutePath().toASCIIString() + "/ResetComputerDetailsSpecifications");
- }
-
- return utils.getValue().createResponse(
- uriInfo.getRequestUri().toASCIIString(),
- entity,
- internal.getHeaderString("ETag"),
- utils.getKey());
- } catch (Exception e) {
- LOG.error("Error retrieving entity", e);
- return xml.createFaultResponse(accept, e);
- }
- } else {
- return internal;
- }
- }
-
- /**
- * Retrieve entity sample.
- *
- * @param accept Accept header.
- * @param entitySetName Entity set name.
- * @param entityId entity id.
- * @param format format query option.
- * @param expand expand query option.
- * @param select select query option.
- * @return entity.
- */
- @GET
- @Path("/{entitySetName}({entityId})")
- public Response getEntity(
- @Context final UriInfo uriInfo,
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @PathParam("entitySetName") final String entitySetName,
- @PathParam("entityId") final String entityId,
- @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
- @QueryParam("$expand") @DefaultValue(StringUtils.EMPTY) final String expand,
- @QueryParam("$select") @DefaultValue(StringUtils.EMPTY) final String select) {
-
- return getEntityInternal(
- uriInfo.getRequestUri().toASCIIString(), accept, entitySetName, entityId, format, expand, select);
- }
-
- protected Response getEntityInternal(
- final String location,
- final String accept,
- final String entitySetName,
- final String entityId,
- final String format,
- final String expand,
- final String select) {
-
- try {
- final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
-
- if (utils.getKey() == Accept.XML || utils.getKey() == Accept.TEXT) {
- throw new UnsupportedMediaTypeException("Unsupported media type");
- }
-
- final Map.Entry<String, InputStream> entityInfo =
- utils.getValue().readEntity(entitySetName, entityId, Accept.ATOM);
-
- final InputStream entity = entityInfo.getValue();
-
- ResWrap<Entity> container = atomDeserializer.toEntity(entity);
- if (container.getContextURL() == null) {
- container = new ResWrap<Entity>(URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX)
- + entitySetName + Constants.get(ConstantKey.ODATA_METADATA_ENTITY_SUFFIX)),
- container.getMetadataETag(), container.getPayload());
- }
- final Entity entry = container.getPayload();
-
- if ((this instanceof KeyAsSegment)) {
- final Link editLink = new Link();
- editLink.setRel("edit");
- editLink.setTitle(entitySetName);
- editLink.setHref(Constants.get(ConstantKey.DEFAULT_SERVICE_URL) + entitySetName + "/" + entityId);
-
- entry.setEditLink(editLink);
- }
-
- if (StringUtils.isNotBlank(select)) {
- final List<String> properties = Arrays.asList(select.split(","));
- final Set<Property> toBeRemoved = new HashSet<Property>();
-
- for (Property property : entry.getProperties()) {
- if (!properties.contains(property.getName())) {
- toBeRemoved.add(property);
- }
- }
-
- entry.getProperties().removeAll(toBeRemoved);
-
- final Set<Link> linkToBeRemoved = new HashSet<Link>();
-
- for (Link link : entry.getNavigationLinks()) {
- if (!properties.contains(link.getTitle().replaceAll("@.*$", "")) && !properties.contains(link.getTitle())) {
- linkToBeRemoved.add(link);
- }
- }
-
- entry.getNavigationLinks().removeAll(linkToBeRemoved);
- }
-
- String tempExpand = expand;
- if (StringUtils.isNotBlank(tempExpand)) {
- tempExpand = StringUtils.substringBefore(tempExpand, "(");
- final List<String> links = Arrays.asList(tempExpand.split(","));
-
- final Map<Link, Link> replace = new HashMap<Link, Link>();
-
- for (Link link : entry.getNavigationLinks()) {
- if (links.contains(link.getTitle())) {
- // expand link
- final Link rep = new Link();
- rep.setHref(link.getHref());
- rep.setRel(link.getRel());
- rep.setTitle(link.getTitle());
- rep.setType(link.getType());
- if (link.getType().equals(Constants.get(ConstantKey.ATOM_LINK_ENTRY))) {
- // inline entry
- final Entity inline = atomDeserializer.toEntity(
- xml.expandEntity(entitySetName, entityId, link.getTitle())).getPayload();
- rep.setInlineEntity(inline);
- } else if (link.getType().equals(Constants.get(ConstantKey.ATOM_LINK_FEED))) {
- // inline feed
- final EntityCollection inline = atomDeserializer.toEntitySet(
- xml.expandEntity(entitySetName, entityId, link.getTitle())).getPayload();
- rep.setInlineEntitySet(inline);
- }
- replace.put(link, rep);
- }
- }
-
- for (Map.Entry<Link, Link> link : replace.entrySet()) {
- entry.getNavigationLinks().remove(link.getKey());
- entry.getNavigationLinks().add(link.getValue());
- }
- }
-
- return xml.createResponse(
- location,
- xml.writeEntity(utils.getKey(), container),
- Commons.getETag(entityInfo.getKey()),
- utils.getKey());
- } catch (Exception e) {
- LOG.error("Error retrieving entity", e);
- return xml.createFaultResponse(accept, e);
- }
- }
-
- @GET
- @Path("/{entitySetName}({entityId})/$value")
- public Response getMediaEntity(
- @Context final UriInfo uriInfo,
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @PathParam("entitySetName") final String entitySetName,
- @PathParam("entityId") final String entityId) {
-
- try {
- if (!accept.contains("*/*") && !accept.contains("application/octet-stream")) {
- throw new UnsupportedMediaTypeException("Unsupported media type");
- }
-
- final AbstractUtilities utils = getUtilities(null);
- final Map.Entry<String, InputStream> entityInfo = utils.readMediaEntity(entitySetName, entityId);
- return utils.createResponse(
- uriInfo.getRequestUri().toASCIIString(),
- entityInfo.getValue(),
- Commons.getETag(entityInfo.getKey()),
- null);
-
- } catch (Exception e) {
- LOG.error("Error retrieving entity", e);
- return xml.createFaultResponse(accept, e);
- }
- }
-
- @DELETE
- @Path("/{entitySetName}({entityId})")
- public Response removeEntity(
- @PathParam("entitySetName") final String entitySetName,
- @PathParam("entityId") final String entityId) {
-
- try {
- final String basePath = entitySetName + File.separatorChar + Commons.getEntityKey(entityId);
-
- FSManager.instance(version).deleteEntity(basePath);
-
- return xml.createResponse(null, null, null, null, Response.Status.NO_CONTENT);
- } catch (Exception e) {
- return xml.createFaultResponse(Accept.XML.toString(), e);
- }
- }
-
- private Response replaceProperty(
- final String location,
- final String accept,
- final String contentType,
- final String prefer,
- final String entitySetName,
- final String entityId,
- final String path,
- final String format,
- final String changes,
- final boolean justValue) {
-
- // if the given path is not about any link then search for property
- LOG.info("Retrieve property {}", path);
-
- try {
- final FSManager fsManager = FSManager.instance(version);
- final String basePath = Commons.getEntityBasePath(entitySetName, entityId);
-
- final ResWrap<Entity> container = xml.readContainerEntity(Accept.ATOM,
- fsManager.readFile(basePath + Constants.get(ConstantKey.ENTITY), Accept.ATOM));
-
- final Entity entry = container.getPayload();
-
- Property toBeReplaced = null;
- for (String element : path.split("/")) {
- if (toBeReplaced == null) {
- toBeReplaced = entry.getProperty(element.trim());
- } else {
- List<Property> value = toBeReplaced.asComplex().getValue();
- for (Property field : value) {
- if (field.getName().equalsIgnoreCase(element)) {
- toBeReplaced = field;
- }
- }
- }
- }
-
- if (toBeReplaced == null) {
- throw new NotFoundException();
- }
-
- if (justValue) {
- // just for primitive values
- toBeReplaced.setValue(ValueType.PRIMITIVE, changes);
- } else {
- final Property pchanges = xml.readProperty(
- Accept.parse(contentType),
- IOUtils.toInputStream(changes, Constants.ENCODING));
-
- toBeReplaced.setValue(pchanges.getValueType(), pchanges.getValue());
- }
-
- fsManager.putInMemory(xml.writeEntity(Accept.ATOM, container),
- fsManager.getAbsolutePath(basePath + Constants.get(ConstantKey.ENTITY), Accept.ATOM));
-
- final Response response;
- if ("return-content".equalsIgnoreCase(prefer)) {
- response = getEntityInternal(location, accept, entitySetName, entityId, format, null, null);
- } else {
- Accept acceptType = null;
- if (StringUtils.isNotBlank(format)) {
- acceptType = Accept.valueOf(format.toUpperCase());
- } else if (StringUtils.isNotBlank(accept)) {
- acceptType = Accept.parse(accept, null);
- }
-
- response = xml.createResponse(null, null, null, acceptType, Response.Status.NO_CONTENT);
- }
-
- if (StringUtils.isNotBlank(prefer)) {
- response.getHeaders().put("Preference-Applied", Collections.<Object> singletonList(prefer));
- }
-
- return response;
- } catch (Exception e) {
- return xml.createFaultResponse(accept, e);
- }
- }
-
- private Response deletePropertyValue(
- final String accept,
- final String prefer,
- final String entitySetName,
- final String entityId,
- final String path,
- final String format) {
- try {
- Accept acceptType = null;
- if (StringUtils.isNotBlank(format)) {
- acceptType = Accept.valueOf(format.toUpperCase());
- } else if (StringUtils.isNotBlank(accept)) {
- acceptType = Accept.parse(accept, null);
- }
-
- // if the given path is not about any link then search for property
- LOG.info("Retrieve property {}", path);
-
- final AbstractUtilities utils = getUtilities(acceptType);
-
- final InputStream changed = utils.deleteProperty(
- entitySetName,
- entityId,
- Arrays.asList(path.split("/")),
- acceptType);
-
- final Response response;
- if ("return-content".equalsIgnoreCase(prefer)) {
- response = xml.createResponse(null, changed, null, acceptType, Response.Status.OK);
- } else {
- changed.close();
- response = xml.createResponse(null, null, null, acceptType, Response.Status.NO_CONTENT);
- }
-
- if (StringUtils.isNotBlank(prefer)) {
- response.getHeaders().put("Preference-Applied", Collections.<Object> singletonList(prefer));
- }
-
- return response;
-
- } catch (Exception e) {
- return xml.createFaultResponse(accept, e);
- }
- }
-
- /**
- * Replace property value.
- *
- * @param accept
- * @param entitySetName
- * @param entityId
- * @param path
- * @param format
- * @param changes
- * @return response
- */
- @PUT
- @Path("/{entitySetName}({entityId})/{path:.*}/$value")
- public Response replacePropertyValue(
- @Context final UriInfo uriInfo,
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
- @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
- @PathParam("entitySetName") final String entitySetName,
- @PathParam("entityId") final String entityId,
- @PathParam("path") final String path,
- @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
- final String changes) {
-
- return replaceProperty(uriInfo.getRequestUri().toASCIIString(),
- accept, contentType, prefer, entitySetName, entityId, path, format, changes, true);
- }
-
- /**
- * Replace property.
- *
- * @param accept
- * @param entitySetName
- * @param entityId
- * @param path
- * @param format
- * @param changes
- * @return response
- */
- @PATCH
- @Path("/{entitySetName}({entityId})/{path:.*}")
- public Response patchProperty(
- @Context final UriInfo uriInfo,
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
- @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
- @PathParam("entitySetName") final String entitySetName,
- @PathParam("entityId") final String entityId,
- @PathParam("path") final String path,
- @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
- final String changes) {
-
- return replaceProperty(uriInfo.getRequestUri().toASCIIString(),
- accept, contentType, prefer, entitySetName, entityId, path, format, changes, false);
- }
-
- @PUT
- @Produces({ MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
- @Consumes({ MediaType.WILDCARD, MediaType.APPLICATION_OCTET_STREAM })
- @Path("/{entitySetName}({entityId})/$value")
- public Response replaceMediaEntity(
- @Context final UriInfo uriInfo,
- @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
- @PathParam("entitySetName") final String entitySetName,
- @PathParam("entityId") final String entityId,
- @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
- final String value) {
- try {
-
- final AbstractUtilities utils = getUtilities(null);
-
- final InputStream res = utils.putMediaInMemory(
- entitySetName, entityId, IOUtils.toInputStream(value, Constants.ENCODING));
-
- final String location = uriInfo.getRequestUri().toASCIIString().replace("/$value", "");
-
- final Response response;
- if ("return-content".equalsIgnoreCase(prefer)) {
- response = xml.createResponse(location, res, null, null, Response.Status.OK);
- } else {
- res.close();
- response = xml.createResponse(location, null, null, null, Response.Status.NO_CONTENT);
- }
-
- if (StringUtils.isNotBlank(prefer)) {
- response.getHeaders().put("Preference-Applied", Collections.<Object> singletonList(prefer));
- }
-
- return response;
-
- } catch (Exception e) {
- LOG.error("Error retrieving entity", e);
- return xml.createFaultResponse(Accept.JSON.toString(), e);
- }
- }
-
- /**
- * Replace property.
- *
- * @param accept
- * @param entitySetName
- * @param entityId
- * @param path
- * @param format
- * @param changes
- * @return response
- */
- @PUT
- @Path("/{entitySetName}({entityId})/{path:.*}")
- public Response replaceProperty(
- @Context final UriInfo uriInfo,
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
- @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
- @PathParam("entitySetName") final String entitySetName,
- @PathParam("entityId") final String entityId,
- @PathParam("path") final String path,
- @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
- final String changes) {
-
- if (xml.isMediaContent(entitySetName + "/" + path)) {
- return replaceMediaProperty(prefer, entitySetName, entityId, path, changes);
- } else {
- return replaceProperty(uriInfo.getRequestUri().toASCIIString(),
- accept, contentType, prefer, entitySetName, entityId, path, format, changes, false);
- }
- }
-
- private Response replaceMediaProperty(
- final String prefer,
- final String entitySetName,
- final String entityId,
- final String path,
- final String value) {
-
- try {
- final AbstractUtilities utils = getUtilities(null);
-
- InputStream res = utils.putMediaInMemory(
- entitySetName, entityId, path, IOUtils.toInputStream(value, Constants.ENCODING));
-
- final Response response;
- if ("return-content".equalsIgnoreCase(prefer)) {
- response = xml.createResponse(null, res, null, null, Response.Status.OK);
- } else {
- res.close();
- response = xml.createResponse(null, null, null, null, Response.Status.NO_CONTENT);
- }
-
- if (StringUtils.isNotBlank(prefer)) {
- response.getHeaders().put("Preference-Applied", Collections.<Object> singletonList(prefer));
- }
-
- return response;
- } catch (Exception e) {
- LOG.error("Error retrieving entity", e);
- return xml.createFaultResponse(Accept.JSON.toString(), e);
- }
- }
-
- /**
- * Nullify property value.
- *
- * @param accept
- * @param entitySetName
- * @param entityId
- * @param path
- * @param format
- * @return response
- */
- @DELETE
- @Path("/{entitySetName}({entityId})/{path:.*}/$value")
- public Response deleteProperty(
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
- @PathParam("entitySetName") final String entitySetName,
- @PathParam("entityId") final String entityId,
- @PathParam("path") final String path,
- @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
- return deletePropertyValue(accept, prefer, entitySetName, entityId, path, format);
- }
-
- /**
- * Retrieve property sample.
- *
- * @param accept Accept header.
- * @param entitySetName Entity set name.
- * @param entityId entity id.
- * @param path path.
- * @param format format query option.
- * @return property.
- */
- @GET
- @Path("/{entitySetName}({entityId})/{path:.*}/$value")
- public Response getPathValue(
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @PathParam("entitySetName") final String entitySetName,
- @PathParam("entityId") final String entityId,
- @PathParam("path") final String path,
- @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
-
- try {
- Accept acceptType = null;
- if (StringUtils.isNotBlank(format)) {
- acceptType = Accept.valueOf(format.toUpperCase());
- } else if (StringUtils.isNotBlank(accept)) {
- acceptType = Accept.parse(accept, null);
- }
-
- return navigateProperty(acceptType, entitySetName, entityId, path, true);
- } catch (Exception e) {
- return xml.createFaultResponse(accept, e);
- }
- }
-
- /**
- * Retrieve property sample.
- *
- * @param accept Accept header.
- * @param entitySetName Entity set name.
- * @param entityId entity id.
- * @param path path.
- * @param format format query option.
- * @return property.
- */
- @GET
- @Path("/{entitySetName}({entityId})/{path:.*}")
- public Response getPath(
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @PathParam("entitySetName") final String entitySetName,
- @PathParam("entityId") final String entityId,
- @PathParam("path") final String path,
- @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
-
- // default utilities
- final AbstractUtilities utils = xml;
-
- try {
- if (utils.isMediaContent(entitySetName + "/" + path)) {
- return navigateStreamedEntity(entitySetName, entityId, path);
- } else {
- Accept acceptType = null;
- if (StringUtils.isNotBlank(format)) {
- acceptType = Accept.valueOf(format.toUpperCase());
- } else if (StringUtils.isNotBlank(accept)) {
- acceptType = Accept.parse(accept, null);
- }
-
- try {
- final LinkInfo linkInfo = xml.readLinks(entitySetName, entityId, path, Accept.XML);
- final Map.Entry<String, List<String>> links = xml.extractLinkURIs(linkInfo.getLinks());
- final InputStream stream = xml.readEntities(links.getValue(), path, links.getKey(), linkInfo.isFeed());
-
- final ByteArrayOutputStream content = new ByteArrayOutputStream();
- final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING);
-
- final ResWrap<?> container = linkInfo.isFeed() ? atomDeserializer.toEntitySet(stream) : atomDeserializer.
- toEntity(stream);
- if (acceptType == Accept.ATOM) {
- atomSerializer.write(writer, container);
- } else {
- jsonSerializer.write(writer, container);
- }
- writer.flush();
- writer.close();
-
- final String basePath = Commons.getEntityBasePath(entitySetName, entityId);
-
- return xml.createResponse(
- null,
- new ByteArrayInputStream(content.toByteArray()),
- Commons.getETag(basePath),
- acceptType);
-
- } catch (NotFoundException e) {
- // if the given path is not about any link then search for property
- return navigateProperty(acceptType, entitySetName, entityId, path, false);
- }
- }
- } catch (Exception e) {
- return utils.createFaultResponse(accept, e);
- }
- }
-
- private Response navigateStreamedEntity(
- final String entitySetName,
- final String entityId,
- final String path) throws Exception {
-
- final AbstractUtilities utils = getUtilities(null);
- final Map.Entry<String, InputStream> entityInfo = utils.readMediaEntity(entitySetName, entityId, path);
- return utils.createResponse(null, entityInfo.getValue(), Commons.getETag(entityInfo.getKey()), null);
- }
-
- private Response navigateProperty(
- final Accept acceptType,
- final String entitySetName,
- final String entityId,
- final String path,
- final boolean searchForValue) throws Exception {
-
- if ((searchForValue && acceptType != null && acceptType != Accept.TEXT) || acceptType == Accept.ATOM) {
- throw new UnsupportedMediaTypeException("Unsupported media type " + acceptType);
- }
-
- final AbstractUtilities utils = getUtilities(acceptType);
-
- final Map.Entry<String, InputStream> entityInfo = utils.readEntity(entitySetName, entityId, Accept.ATOM);
-
- final InputStream entity = entityInfo.getValue();
-
- final ResWrap<Entity> entryContainer = atomDeserializer.toEntity(entity);
-
- final String[] pathElems = StringUtils.split(path, "/");
- Property property = entryContainer.getPayload().getProperty(pathElems[0]);
- if (pathElems.length > 1 && property.isComplex()) {
- for (Property sub : property.asComplex().getValue()) {
- if (pathElems[1].equals(sub.getName())) {
- property = sub;
- if (pathElems.length > 2 && property.isComplex()) {
- for (Property subsub : property.asComplex().getValue()) {
- if (pathElems[2].equals(subsub.getName())) {
- property = subsub;
- }
- }
- }
- }
- }
- }
-
- final ResWrap<Property> container = new ResWrap<Property>(
- URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX) + entitySetName + "(" + entityId + ")/" + path),
- entryContainer.getMetadataETag(),
- property);
-
- return xml.createResponse(null,
- searchForValue ? IOUtils.toInputStream(
- container.getPayload().isNull() ? StringUtils.EMPTY : stringValue(container.getPayload()),
- Constants.ENCODING) : utils.writeProperty(acceptType, container),
- Commons.getETag(Commons.getEntityBasePath(entitySetName, entityId)),
- acceptType);
- }
-
- private String stringValue(final Property property) {
- EdmPrimitiveTypeKind kind = EdmPrimitiveTypeKind.valueOfFQN(property.getType());
- try {
- return EdmPrimitiveTypeFactory.getInstance(kind)
- .valueToString(property.asPrimitive(), null, null,
- org.apache.olingo.commons.api.Constants.DEFAULT_PRECISION,
- org.apache.olingo.commons.api.Constants.DEFAULT_SCALE, null);
- } catch (final EdmPrimitiveTypeException e) {
- return property.asPrimitive().toString();
- }
- }
-
- /**
- * Count sample.
- *
- * @param accept Accept header.
- * @param entitySetName entity set name.
- * @return count.
- */
- @GET
- @Path("/{entitySetName}/$count")
- public Response count(
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
- @PathParam("entitySetName") final String entitySetName) {
- try {
- final Accept acceptType = Accept.parse(accept, Accept.TEXT);
-
- if (acceptType != Accept.TEXT) {
- throw new UnsupportedMediaTypeException("Unsupported type " + accept);
- }
-
- int count = xml.countAllElements(entitySetName);
-
- final Response.ResponseBuilder builder = Response.ok();
- builder.entity(count);
-
- return builder.build();
- } catch (Exception e) {
- return xml.createFaultResponse(accept, e);
- }
- }
-
- public Map.Entry<Accept, AbstractUtilities> getUtilities(final String accept, final String format) {
- Accept acceptType;
- if (StringUtils.isNotBlank(format)) {
- try {
- acceptType = Accept.valueOf(format.toUpperCase());
- } catch (Exception e) {
- acceptType = Accept.parse(format);
- }
- } else {
- acceptType = Accept.parse(accept);
- }
-
- return new AbstractMap.SimpleEntry<Accept, AbstractUtilities>(acceptType, getUtilities(acceptType));
- }
-
- protected AbstractUtilities getUtilities(final Accept accept) {
- final AbstractUtilities utils;
- if (accept == Accept.XML || accept == Accept.TEXT || accept == Accept.ATOM) {
- utils = xml;
- } else {
- utils = json;
- }
-
- return utils;
- }
-
- protected void updateInlineEntities(final Entity entity) {
- final String type = entity.getType();
- EntityType entityType;
- Map<String, NavigationProperty> navProperties = Collections.emptyMap();
- if (type != null && type.length() > 0) {
- entityType = metadata.getEntityOrComplexType(type);
- navProperties = entityType.getNavigationPropertyMap();
- }
-
- for (Property property : entity.getProperties()) {
- if (navProperties.containsKey(property.getName())) {
- Link alink = new Link();
- alink.setTitle(property.getName());
- alink.getAnnotations().addAll(property.getAnnotations());
-
- alink.setType(navProperties.get(property.getName()).isEntitySet()
- ? Constants.get(ConstantKey.ATOM_LINK_FEED)
- : Constants.get(ConstantKey.ATOM_LINK_ENTRY));
-
- alink.setRel(Constants.get(ConstantKey.ATOM_LINK_REL) + property.getName());
-
- if (property.isCollection()) {
- EntityCollection inline = new EntityCollection();
- for (Object value : property.asCollection()) {
- Entity inlineEntity = new Entity();
- inlineEntity.setType(navProperties.get(property.getName()).getType());
- for (Property prop : ((ComplexValue) value).getValue()) {
- inlineEntity.getProperties().add(prop);
- }
- inline.getEntities().add(inlineEntity);
- }
- alink.setInlineEntitySet(inline);
- } else if (property.isComplex()) {
- Entity inline = new Entity();
- inline.setType(navProperties.get(property.getName()).getType());
- for (Property prop : property.asComplex().getValue()) {
- inline.getProperties().add(prop);
- }
- alink.setInlineEntity(inline);
-
- } else {
- throw new IllegalStateException("Invalid navigation property " + property);
- }
- entity.getNavigationLinks().add(alink);
- }
- }
- }
-
- protected void normalizeAtomEntry(final Entity entry, final String entitySetName, final String entityKey) {
- final org.apache.olingo.fit.metadata.EntitySet entitySet = metadata.getEntitySet(entitySetName);
- final EntityType entityType = metadata.getEntityOrComplexType(entitySet.getType());
- for (Map.Entry<String, org.apache.olingo.fit.metadata.Property> property : entityType.getPropertyMap().entrySet()) {
- if (entry.getProperty(property.getKey()) == null && property.getValue().isNullable()) {
- final Property prop = new Property();
- prop.setName(property.getKey());
- prop.setValue(ValueType.PRIMITIVE, null);
- entry.getProperties().add(prop);
- }
- }
-
- for (Map.Entry<String, NavigationProperty> property : entityType.getNavigationPropertyMap().entrySet()) {
- boolean found = false;
- for (Link link : entry.getNavigationLinks()) {
- if (link.getTitle().equals(property.getKey())) {
- found = true;
- }
- }
-
- if (!found) {
- final Link link = new Link();
- link.setTitle(property.getKey());
- link.setType(property.getValue().isEntitySet()
- ? Constants.get(ConstantKey.ATOM_LINK_FEED)
- : Constants.get(ConstantKey.ATOM_LINK_ENTRY));
- link.setRel(Constants.get(ConstantKey.ATOM_LINK_REL) + property.getKey());
- link.setHref(entitySetName + "(" + entityKey + ")/" + property.getKey());
- entry.getNavigationLinks().add(link);
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/Demo.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/Demo.java b/fit/src/main/java/org/apache/olingo/fit/Demo.java
index c591f01..697b7c9 100644
--- a/fit/src/main/java/org/apache/olingo/fit/Demo.java
+++ b/fit/src/main/java/org/apache/olingo/fit/Demo.java
@@ -40,7 +40,6 @@ import javax.ws.rs.core.UriInfo;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
-import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
import org.apache.olingo.fit.metadata.Metadata;
import org.apache.olingo.fit.methods.PATCH;
import org.apache.olingo.fit.utils.Accept;
@@ -54,7 +53,7 @@ import org.springframework.stereotype.Service;
public class Demo extends Services {
public Demo() throws IOException {
- super(new Metadata(FSManager.instance(ODataServiceVersion.V40).
+ super(new Metadata(FSManager.instance().
readRes("demo" + StringUtils.capitalize(Constants.get(ConstantKey.METADATA)), Accept.XML)));
}
@@ -166,9 +165,8 @@ public class Demo extends Services {
@HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
@PathParam("entitySetName") final String entitySetName,
@PathParam("entityId") final String entityId,
- @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
final String value) {
- return super.replaceMediaEntity(uriInfo, prefer, entitySetName, entityId, format, value);
+ return super.replaceMediaEntity(uriInfo, prefer, entitySetName, entityId, value);
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/OpenType.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/OpenType.java b/fit/src/main/java/org/apache/olingo/fit/OpenType.java
index e65c5bf..a15128e 100644
--- a/fit/src/main/java/org/apache/olingo/fit/OpenType.java
+++ b/fit/src/main/java/org/apache/olingo/fit/OpenType.java
@@ -40,7 +40,6 @@ import javax.ws.rs.core.UriInfo;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
-import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
import org.apache.olingo.fit.metadata.Metadata;
import org.apache.olingo.fit.utils.Accept;
import org.apache.olingo.fit.utils.ConstantKey;
@@ -53,8 +52,8 @@ import org.springframework.stereotype.Service;
public class OpenType extends Services {
public OpenType() throws IOException {
- super(new Metadata(FSManager.instance(ODataServiceVersion.V40).
- readRes("openType" + StringUtils.capitalize(Constants.get(ConstantKey.METADATA)), Accept.XML)));
+ super(new Metadata(FSManager.instance()
+ .readRes("openType" + StringUtils.capitalize(Constants.get(ConstantKey.METADATA)), Accept.XML)));
}
private Response replaceServiceName(final Response response) {
[05/22] olingo-odata4 git commit: [OLINGO-834] better alias support
in URI parser
Posted by mi...@apache.org.
[OLINGO-834] better alias support in URI parser
Signed-off-by: Christian Amend <ch...@sap.com>
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/110c7b0e
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/110c7b0e
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/110c7b0e
Branch: refs/heads/OLINGO-832_StreamSerializerPoC
Commit: 110c7b0e5afa1f9f717d95ca48bd5c695821db06
Parents: b317b90
Author: Klaus Straubinger <kl...@sap.com>
Authored: Thu Feb 4 12:24:38 2016 +0100
Committer: Christian Amend <ch...@sap.com>
Committed: Thu Feb 4 12:38:10 2016 +0100
----------------------------------------------------------------------
.../uri/queryoption/SystemQueryOptionKind.java | 22 +-
.../apache/olingo/server/core/ODataHandler.java | 4 +-
.../server/core/ODataHttpHandlerImpl.java | 19 +-
.../olingo/server/core/uri/UriInfoImpl.java | 37 +-
.../server/core/uri/parser/ExpandParser.java | 30 +-
.../core/uri/parser/ExpressionParser.java | 85 ++-
.../server/core/uri/parser/FilterParser.java | 6 +-
.../server/core/uri/parser/OrderByParser.java | 6 +-
.../olingo/server/core/uri/parser/Parser.java | 354 +++++++------
.../server/core/uri/parser/ParserHelper.java | 168 ++++--
.../core/uri/parser/ResourcePathParser.java | 38 +-
.../server/core/uri/parser/SelectParser.java | 12 +-
.../server/core/uri/parser/UriTokenizer.java | 12 +-
.../uri/queryoption/expression/AliasImpl.java | 9 +-
.../uri/validator/UriValidationException.java | 4 +-
.../server/core/uri/validator/UriValidator.java | 513 +++++--------------
.../server-core-exceptions-i18n.properties | 1 +
.../olingo/server/core/uri/UriInfoImplTest.java | 50 +-
.../core/uri/parser/ExpressionParserTest.java | 2 +-
.../core/uri/parser/UriTokenizerTest.java | 3 +
.../olingo/server/tecsvc/data/DataProvider.java | 12 +-
.../SystemQueryOptionsRuntimeException.java | 3 +-
.../tecsvc/provider/ContainerProvider.java | 6 +-
.../core/uri/parser/TestFullResourcePath.java | 112 ++--
.../core/uri/queryoption/QueryOptionTest.java | 4 +-
.../queryoption/expression/ExpressionTest.java | 6 +-
.../core/uri/testutil/FilterValidator.java | 51 +-
.../core/uri/validator/UriValidatorTest.java | 68 +--
28 files changed, 797 insertions(+), 840 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/SystemQueryOptionKind.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/SystemQueryOptionKind.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/SystemQueryOptionKind.java
index f0c907b..d5d60a1 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/SystemQueryOptionKind.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/SystemQueryOptionKind.java
@@ -18,10 +18,10 @@
*/
package org.apache.olingo.server.api.uri.queryoption;
+
/**
* Defines the supported system query options.
*/
-
public enum SystemQueryOptionKind {
/**
@@ -84,12 +84,30 @@ public enum SystemQueryOptionKind {
*/
LEVELS("$levels");
- private String syntax;
+ private final String syntax;
SystemQueryOptionKind(final String syntax) {
this.syntax = syntax;
}
+ /**
+ * Converts the URI syntax to an enumeration value.
+ * @param option option in the syntax used in the URI
+ * @return system query option kind representing the given option
+ * (or <code>null</code> if the option does not represent a system query option)
+ */
+ public static SystemQueryOptionKind get(final String option) {
+ for (final SystemQueryOptionKind kind : values()) {
+ if (kind.syntax.equals(option)) {
+ return kind;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return URI syntax for this system query option
+ */
@Override
public String toString() {
return syntax;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
index 96b419c..3baaac7 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
@@ -160,6 +160,7 @@ public class ODataHandler {
public void handleException(final ODataRequest request, final ODataResponse response,
final ODataServerError serverError, final Exception exception) {
+ final int measurementHandle = debugger.startRuntimeMeasurement("ODataHandler", "handleException");
lastThrownException = exception;
ErrorProcessor exceptionProcessor;
try {
@@ -176,8 +177,9 @@ public class ODataHandler {
} catch (final ContentNegotiatorException e) {
requestedContentType = ContentType.JSON;
}
- final int measurementHandle = debugger.startRuntimeMeasurement("ErrorProcessor", "processError");
+ final int measurementError = debugger.startRuntimeMeasurement("ErrorProcessor", "processError");
exceptionProcessor.processError(request, response, serverError, requestedContentType);
+ debugger.stopRuntimeMeasurement(measurementError);
debugger.stopRuntimeMeasurement(measurementHandle);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
index 55c1194..61581c0 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
@@ -24,7 +24,7 @@ import java.nio.channels.Channel;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
-import java.util.ArrayList;
+import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.List;
@@ -191,8 +191,12 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler {
odRequest.setBody(httpRequest.getInputStream());
odRequest.setProtocol(httpRequest.getProtocol());
odRequest.setMethod(extractMethod(httpRequest));
+ int innerHandle = debugger.startRuntimeMeasurement("ODataHttpHandlerImpl", "copyHeaders");
copyHeaders(odRequest, httpRequest);
+ debugger.stopRuntimeMeasurement(innerHandle);
+ innerHandle = debugger.startRuntimeMeasurement("ODataHttpHandlerImpl", "fillUriInformation");
fillUriInformation(odRequest, httpRequest, split);
+ debugger.stopRuntimeMeasurement(innerHandle);
return odRequest;
} catch (final IOException e) {
@@ -273,14 +277,11 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler {
odRequest.setRawServiceResolutionUri(rawServiceResolutionUri);
}
- static void copyHeaders(final ODataRequest odRequest, final HttpServletRequest req) {
- for (Enumeration<?> headerNames = req.getHeaderNames(); headerNames.hasMoreElements();) {
- String headerName = (String) headerNames.nextElement();
- List<String> headerValues = new ArrayList<String>();
- for (Enumeration<?> headers = req.getHeaders(headerName); headers.hasMoreElements();) {
- String value = (String) headers.nextElement();
- headerValues.add(value);
- }
+ static void copyHeaders(ODataRequest odRequest, final HttpServletRequest req) {
+ for (final Enumeration<?> headerNames = req.getHeaderNames(); headerNames.hasMoreElements();) {
+ final String headerName = (String) headerNames.nextElement();
+ @SuppressWarnings("unchecked") // getHeaders() says it returns an Enumeration of String.
+ final List<String> headerValues = Collections.list(req.getHeaders(headerName));
odRequest.addHeader(headerName, headerValues);
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriInfoImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriInfoImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriInfoImpl.java
index e6fe057..7183bde 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriInfoImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriInfoImpl.java
@@ -20,6 +20,7 @@ package org.apache.olingo.server.core.uri;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -64,7 +65,7 @@ public class UriInfoImpl implements UriInfo {
private List<UriResource> pathParts = new ArrayList<UriResource>();
private Map<SystemQueryOptionKind, SystemQueryOption> systemQueryOptions =
- new HashMap<SystemQueryOptionKind, SystemQueryOption>();
+ new EnumMap<SystemQueryOptionKind, SystemQueryOption>(SystemQueryOptionKind.class);
private Map<String, AliasQueryOption> aliases = new HashMap<String, AliasQueryOption>();
private List<CustomQueryOption> customQueryOptions = new ArrayList<CustomQueryOption>();
@@ -155,15 +156,13 @@ public class UriInfoImpl implements UriInfo {
return Collections.unmodifiableList(pathParts);
}
- public UriInfoImpl setQueryOptions(final List<QueryOption> list) {
- for (final QueryOption item : list) {
- if (item instanceof SystemQueryOption) {
- setSystemQueryOption((SystemQueryOption) item);
- } else if (item instanceof AliasQueryOption) {
- addAlias((AliasQueryOption) item);
- } else if (item instanceof CustomQueryOption) {
- addCustomQueryOption((CustomQueryOption) item);
- }
+ public UriInfoImpl setQueryOption(final QueryOption option) {
+ if (option instanceof SystemQueryOption) {
+ setSystemQueryOption((SystemQueryOption) option);
+ } else if (option instanceof AliasQueryOption) {
+ addAlias((AliasQueryOption) option);
+ } else if (option instanceof CustomQueryOption) {
+ addCustomQueryOption((CustomQueryOption) option);
}
return this;
}
@@ -263,18 +262,22 @@ public class UriInfoImpl implements UriInfo {
}
public UriInfoImpl addAlias(final AliasQueryOption alias) {
- aliases.put(alias.getName(), alias);
+ if (aliases.containsKey(alias.getName())) {
+ throw new ODataRuntimeException("Alias " + alias.getName() + " is already there.");
+ } else {
+ aliases.put(alias.getName(), alias);
+ }
return this;
}
@Override
public String getValueForAlias(final String alias) {
- final AliasQueryOption aliasQueryOption = getAlias(alias);
+ final AliasQueryOption aliasQueryOption = aliases.get(alias);
return aliasQueryOption == null ? null : aliasQueryOption.getText();
}
- public AliasQueryOption getAlias(final String key) {
- return aliases.get(key);
+ public Map<String, AliasQueryOption> getAliasMap() {
+ return Collections.unmodifiableMap(aliases);
}
@Override
@@ -282,8 +285,10 @@ public class UriInfoImpl implements UriInfo {
return Collections.unmodifiableList(new ArrayList<AliasQueryOption>(aliases.values()));
}
- public UriInfoImpl addCustomQueryOption(final CustomQueryOption item) {
- customQueryOptions.add(item);
+ public UriInfoImpl addCustomQueryOption(final CustomQueryOption option) {
+ if (option.getName() != null && !option.getName().isEmpty()) {
+ customQueryOptions.add(option);
+ }
return this;
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpandParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpandParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpandParser.java
index d8209d8..03750a5 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpandParser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpandParser.java
@@ -18,6 +18,8 @@
*/
package org.apache.olingo.server.core.uri.parser;
+import java.util.Map;
+
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
@@ -30,6 +32,7 @@ import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.uri.UriInfoKind;
import org.apache.olingo.server.api.uri.UriResourceNavigation;
import org.apache.olingo.server.api.uri.UriResourcePartTyped;
+import org.apache.olingo.server.api.uri.queryoption.AliasQueryOption;
import org.apache.olingo.server.api.uri.queryoption.ExpandItem;
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
import org.apache.olingo.server.api.uri.queryoption.LevelsExpandOption;
@@ -53,10 +56,12 @@ public class ExpandParser {
private final Edm edm;
private final OData odata;
+ private final Map<String, AliasQueryOption> aliases;
- public ExpandParser(final Edm edm, final OData odata) {
+ public ExpandParser(final Edm edm, final OData odata, final Map<String, AliasQueryOption> aliases) {
this.edm = edm;
this.odata = odata;
+ this.aliases = aliases;
}
public ExpandOption parse(UriTokenizer tokenizer, final EdmStructuredType referencedType)
@@ -92,7 +97,7 @@ public class ExpandParser {
ParserHelper.requireNext(tokenizer, TokenKind.SLASH);
}
- UriInfoImpl resource = parseExpandPath(tokenizer, referencedType);
+ UriInfoImpl resource = parseExpandPath(tokenizer, referencedType, item);
UriResourcePartTyped lastPart = (UriResourcePartTyped) resource.getLastResourcePart();
@@ -156,8 +161,8 @@ public class ExpandParser {
return null;
}
- private UriInfoImpl parseExpandPath(UriTokenizer tokenizer, final EdmStructuredType referencedType)
- throws UriParserException {
+ private UriInfoImpl parseExpandPath(UriTokenizer tokenizer, final EdmStructuredType referencedType,
+ ExpandItemImpl item) throws UriParserException {
UriInfoImpl resource = new UriInfoImpl().setKind(UriInfoKind.resource);
EdmStructuredType type = referencedType;
@@ -181,10 +186,13 @@ public class ExpandParser {
final EdmNavigationProperty navigationProperty = type.getNavigationProperty(name);
if (navigationProperty == null) {
- // TODO: could also have been star after complex property (and maybe type cast)
- throw new UriParserSemanticException(
- "Navigation Property '" + name + "' not found in type '" + type.getFullQualifiedName() + "'.",
- UriParserSemanticException.MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE, type.getName(), name);
+ if (tokenizer.next(TokenKind.STAR)) {
+ item.setIsStar(true);
+ } else {
+ throw new UriParserSemanticException(
+ "Navigation Property '" + name + "' not found in type '" + type.getFullQualifiedName() + "'.",
+ UriParserSemanticException.MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE, type.getName(), name);
+ }
} else {
resource.addResourcePart(new UriResourceNavigationPropertyImpl(navigationProperty));
}
@@ -209,11 +217,11 @@ public class ExpandParser {
} else if (!forRef && !forCount && tokenizer.next(TokenKind.EXPAND)) {
ParserHelper.requireNext(tokenizer, TokenKind.EQ);
- systemQueryOption = new ExpandParser(edm, odata).parse(tokenizer, referencedType);
+ systemQueryOption = new ExpandParser(edm, odata, aliases).parse(tokenizer, referencedType);
} else if (tokenizer.next(TokenKind.FILTER)) {
ParserHelper.requireNext(tokenizer, TokenKind.EQ);
- systemQueryOption = new FilterParser(edm, odata).parse(tokenizer, referencedType, null);
+ systemQueryOption = new FilterParser(edm, odata).parse(tokenizer, referencedType, null, aliases);
} else if (!forRef && !forCount && tokenizer.next(TokenKind.LEVELS)) {
ParserHelper.requireNext(tokenizer, TokenKind.EQ);
@@ -221,7 +229,7 @@ public class ExpandParser {
} else if (!forCount && tokenizer.next(TokenKind.ORDERBY)) {
ParserHelper.requireNext(tokenizer, TokenKind.EQ);
- systemQueryOption = new OrderByParser(edm, odata).parse(tokenizer, referencedType, null);
+ systemQueryOption = new OrderByParser(edm, odata).parse(tokenizer, referencedType, null, aliases);
} else if (tokenizer.next(TokenKind.SEARCH)) {
ParserHelper.requireNext(tokenizer, TokenKind.EQ);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpressionParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpressionParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpressionParser.java
index 1cf279e..a0ec676 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpressionParser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpressionParser.java
@@ -24,7 +24,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
-import java.util.HashMap;
+import java.util.EnumMap;
import java.util.List;
import java.util.Map;
@@ -53,6 +53,7 @@ import org.apache.olingo.server.api.uri.UriResourceFunction;
import org.apache.olingo.server.api.uri.UriResourceLambdaVariable;
import org.apache.olingo.server.api.uri.UriResourceNavigation;
import org.apache.olingo.server.api.uri.UriResourcePartTyped;
+import org.apache.olingo.server.api.uri.queryoption.AliasQueryOption;
import org.apache.olingo.server.api.uri.queryoption.expression.Alias;
import org.apache.olingo.server.api.uri.queryoption.expression.Binary;
import org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKind;
@@ -96,7 +97,7 @@ import org.apache.olingo.server.core.uri.validator.UriValidationException;
public class ExpressionParser {
private static final Map<TokenKind, BinaryOperatorKind> tokenToBinaryOperator;
static {
- Map<TokenKind, BinaryOperatorKind> temp = new HashMap<TokenKind, BinaryOperatorKind>();
+ Map<TokenKind, BinaryOperatorKind> temp = new EnumMap<TokenKind, BinaryOperatorKind>(TokenKind.class);
temp.put(TokenKind.OrOperator, BinaryOperatorKind.OR);
temp.put(TokenKind.AndOperator, BinaryOperatorKind.AND);
@@ -121,7 +122,7 @@ public class ExpressionParser {
// 'cast' and 'isof' are handled specially.
private static final Map<TokenKind, MethodKind> tokenToMethod;
static {
- Map<TokenKind, MethodKind> temp = new HashMap<TokenKind, MethodKind>();
+ Map<TokenKind, MethodKind> temp = new EnumMap<TokenKind, MethodKind>(TokenKind.class);
temp.put(TokenKind.CeilingMethod, MethodKind.CEILING);
temp.put(TokenKind.ConcatMethod, MethodKind.CONCAT);
temp.put(TokenKind.ContainsMethod, MethodKind.CONTAINS);
@@ -163,6 +164,7 @@ public class ExpressionParser {
private Deque<UriResourceLambdaVariable> lambdaVariables = new ArrayDeque<UriResourceLambdaVariable>();
private EdmType referringType;
private Collection<String> crossjoinEntitySetNames;
+ private Map<String, AliasQueryOption> aliases;
public ExpressionParser(final Edm edm, final OData odata) {
this.edm = edm;
@@ -170,12 +172,13 @@ public class ExpressionParser {
}
public Expression parse(UriTokenizer tokenizer, final EdmType referringType,
- final Collection<String> crossjoinEntitySetNames)
+ final Collection<String> crossjoinEntitySetNames, final Map<String, AliasQueryOption> aliases)
throws UriParserException, UriValidationException {
// Initialize tokenizer.
this.tokenizer = tokenizer;
this.referringType = referringType;
this.crossjoinEntitySetNames = crossjoinEntitySetNames;
+ this.aliases = aliases;
return parseExpression();
}
@@ -339,7 +342,14 @@ public class ExpressionParser {
}
if (tokenizer.next(TokenKind.ParameterAliasName)) {
- return new AliasImpl(tokenizer.getText());
+ final String name = tokenizer.getText();
+ if (aliases.containsKey(name)) {
+ return new AliasImpl(name,
+ ParserHelper.parseAliasValue(name, null, true, true, edm, referringType, aliases));
+ } else {
+ throw new UriValidationException("Alias '" + name + "' not found.",
+ UriValidationException.MessageKeys.MISSING_ALIAS, name);
+ }
}
if (tokenizer.next(TokenKind.jsonArrayOrObject)) {
@@ -360,7 +370,8 @@ public class ExpressionParser {
return parsePrimitive(nextPrimitive);
}
- final TokenKind nextMethod = nextMethod();
+ final TokenKind nextMethod =
+ ParserHelper.next(tokenizer, tokenToMethod.keySet().toArray(new TokenKind[tokenToMethod.size()]));
if (nextMethod != null) {
return parseMethod(nextMethod);
}
@@ -630,7 +641,7 @@ public class ExpressionParser {
} else {
ParserHelper.requireNext(tokenizer, TokenKind.OPEN);
final List<UriParameter> keyPredicates =
- ParserHelper.parseKeyPredicate(tokenizer, entitySet.getEntityType(), null);
+ ParserHelper.parseKeyPredicate(tokenizer, entitySet.getEntityType(), null, edm, referringType, aliases);
resource = new UriResourceEntitySetImpl(entitySet).setKeyPredicates(keyPredicates);
}
uriInfo.addResourcePart(resource);
@@ -777,7 +788,8 @@ public class ExpressionParser {
final UriResourceNavigationPropertyImpl navigationResource =
new UriResourceNavigationPropertyImpl((EdmNavigationProperty) property);
navigationResource.setKeyPredicates(
- ParserHelper.parseNavigationKeyPredicate(tokenizer, (EdmNavigationProperty) property));
+ ParserHelper.parseNavigationKeyPredicate(tokenizer, (EdmNavigationProperty) property,
+ edm, referringType, aliases));
uriInfo.addResourcePart(navigationResource);
if (navigationResource.isCollection()) {
@@ -830,13 +842,16 @@ public class ExpressionParser {
if (lastResource instanceof UriResourceNavigation) {
((UriResourceNavigationPropertyImpl) lastResource).setKeyPredicates(
ParserHelper.parseNavigationKeyPredicate(tokenizer,
- ((UriResourceNavigationPropertyImpl) lastResource).getProperty()));
+ ((UriResourceNavigationPropertyImpl) lastResource).getProperty(), edm, referringType, aliases));
} else if (lastResource instanceof UriResourceFunction
&& ((UriResourceFunction) lastResource).getType() instanceof EdmEntityType) {
((UriResourceFunctionImpl) lastResource).setKeyPredicates(
ParserHelper.parseKeyPredicate(tokenizer,
(EdmEntityType) ((UriResourceFunction) lastResource).getType(),
- null));
+ null,
+ edm,
+ referringType,
+ aliases));
} else {
throw new UriParserSemanticException("Unknown or wrong resource type.",
UriParserSemanticException.MessageKeys.NOT_IMPLEMENTED, lastResource.toString());
@@ -911,18 +926,21 @@ public class ExpressionParser {
private void parseFunction(final FullQualifiedName fullQualifiedName, UriInfoImpl uriInfo,
final EdmType lastType, final boolean lastIsCollection) throws UriParserException, UriValidationException {
- final List<UriParameter> parameters = ParserHelper.parseFunctionParameters(tokenizer, edm, referringType, true);
+ final List<UriParameter> parameters =
+ ParserHelper.parseFunctionParameters(tokenizer, edm, referringType, true, aliases);
final List<String> parameterNames = ParserHelper.getParameterNames(parameters);
final EdmFunction boundFunction = edm.getBoundFunction(fullQualifiedName,
lastType.getFullQualifiedName(), lastIsCollection, parameterNames);
if (boundFunction != null) {
+ ParserHelper.validateFunctionParameters(boundFunction, parameters, edm, referringType, aliases);
parseFunctionRest(uriInfo, boundFunction, parameters);
return;
}
final EdmFunction unboundFunction = edm.getUnboundFunction(fullQualifiedName, parameterNames);
if (unboundFunction != null) {
+ ParserHelper.validateFunctionParameters(unboundFunction, parameters, edm, referringType, aliases);
parseFunctionRest(uriInfo, unboundFunction, parameters);
return;
}
@@ -934,7 +952,8 @@ public class ExpressionParser {
private void parseBoundFunction(final FullQualifiedName fullQualifiedName, UriInfoImpl uriInfo,
final UriResourcePartTyped lastResource) throws UriParserException, UriValidationException {
final EdmType type = lastResource.getType();
- final List<UriParameter> parameters = ParserHelper.parseFunctionParameters(tokenizer, edm, referringType, true);
+ final List<UriParameter> parameters =
+ ParserHelper.parseFunctionParameters(tokenizer, edm, referringType, true, aliases);
final List<String> parameterNames = ParserHelper.getParameterNames(parameters);
final EdmFunction boundFunction = edm.getBoundFunction(fullQualifiedName,
type.getFullQualifiedName(), lastResource.isCollection(), parameterNames);
@@ -942,6 +961,7 @@ public class ExpressionParser {
throw new UriParserSemanticException("Bound function '" + fullQualifiedName + "' not found.",
UriParserSemanticException.MessageKeys.FUNCTION_NOT_FOUND, fullQualifiedName.getFullQualifiedNameAsString());
}
+ ParserHelper.validateFunctionParameters(boundFunction, parameters, edm, referringType, aliases);
parseFunctionRest(uriInfo, boundFunction, parameters);
}
@@ -1010,40 +1030,6 @@ public class ExpressionParser {
}
}
- private TokenKind nextMethod() {
- return ParserHelper.next(tokenizer,
- TokenKind.CeilingMethod,
- TokenKind.ConcatMethod,
- TokenKind.ContainsMethod,
- TokenKind.DateMethod,
- TokenKind.DayMethod,
- TokenKind.EndswithMethod,
- TokenKind.FloorMethod,
- TokenKind.FractionalsecondsMethod,
- TokenKind.GeoDistanceMethod,
- TokenKind.GeoIntersectsMethod,
- TokenKind.GeoLengthMethod,
- TokenKind.HourMethod,
- TokenKind.IndexofMethod,
- TokenKind.LengthMethod,
- TokenKind.MaxdatetimeMethod,
- TokenKind.MindatetimeMethod,
- TokenKind.MinuteMethod,
- TokenKind.MonthMethod,
- TokenKind.NowMethod,
- TokenKind.RoundMethod,
- TokenKind.SecondMethod,
- TokenKind.StartswithMethod,
- TokenKind.SubstringMethod,
- TokenKind.TimeMethod,
- TokenKind.TolowerMethod,
- TokenKind.TotaloffsetminutesMethod,
- TokenKind.TotalsecondsMethod,
- TokenKind.ToupperMethod,
- TokenKind.TrimMethod,
- TokenKind.YearMethod);
- }
-
protected static EdmType getType(final Expression expression) throws UriParserException {
EdmType type;
if (expression instanceof Literal) {
@@ -1060,11 +1046,12 @@ public class ExpressionParser {
type = ((BinaryImpl) expression).getType();
} else if (expression instanceof Method) {
type = ((MethodImpl) expression).getType();
+ } else if (expression instanceof Alias) {
+ final AliasQueryOption alias = ((AliasImpl) expression).getAlias();
+ type = alias == null || alias.getValue() == null ? null : getType(alias.getValue());
} else if (expression instanceof LambdaRef) {
throw new UriParserSemanticException("Type determination not implemented.",
UriParserSemanticException.MessageKeys.NOT_IMPLEMENTED, expression.toString());
- } else if (expression instanceof Alias) {
- type = null; // The alias would have to be available already parsed.
} else {
throw new UriParserSemanticException("Unknown expression type.",
UriParserSemanticException.MessageKeys.NOT_IMPLEMENTED, expression.toString());
@@ -1142,7 +1129,7 @@ public class ExpressionParser {
private Enumeration createEnumExpression(final String primitiveValueLiteral) throws UriParserException {
final EdmEnumType enumType = getEnumType(primitiveValueLiteral);
- // TODO: Can the Enumeration interface be changed to handle the value as a whole?
+ // The Enumeration interface could be extended to handle the value as a whole, in line with the primitive type.
try {
return new EnumerationImpl(enumType,
Arrays.asList(enumType.fromUriLiteral(primitiveValueLiteral).split(",")));
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/FilterParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/FilterParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/FilterParser.java
index dd73009..f20b029 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/FilterParser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/FilterParser.java
@@ -19,11 +19,13 @@
package org.apache.olingo.server.core.uri.parser;
import java.util.Collection;
+import java.util.Map;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.uri.queryoption.AliasQueryOption;
import org.apache.olingo.server.api.uri.queryoption.FilterOption;
import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
import org.apache.olingo.server.core.uri.queryoption.FilterOptionImpl;
@@ -40,10 +42,10 @@ public class FilterParser {
}
public FilterOption parse(UriTokenizer tokenizer, final EdmType referencedType,
- final Collection<String> crossjoinEntitySetNames)
+ final Collection<String> crossjoinEntitySetNames, final Map<String, AliasQueryOption> aliases)
throws UriParserException, UriValidationException {
final Expression filterExpression = new ExpressionParser(edm, odata)
- .parse(tokenizer, referencedType, crossjoinEntitySetNames);
+ .parse(tokenizer, referencedType, crossjoinEntitySetNames, aliases);
final EdmType type = ExpressionParser.getType(filterExpression);
if (type == null || type.equals(odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Boolean))) {
return new FilterOptionImpl().setExpression(filterExpression);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/OrderByParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/OrderByParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/OrderByParser.java
index 5ea8cb7..b008ed6 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/OrderByParser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/OrderByParser.java
@@ -19,10 +19,12 @@
package org.apache.olingo.server.core.uri.parser;
import java.util.Collection;
+import java.util.Map;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmStructuredType;
import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.uri.queryoption.AliasQueryOption;
import org.apache.olingo.server.api.uri.queryoption.OrderByOption;
import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
import org.apache.olingo.server.core.uri.parser.UriTokenizer.TokenKind;
@@ -41,12 +43,12 @@ public class OrderByParser {
}
public OrderByOption parse(UriTokenizer tokenizer, final EdmStructuredType referencedType,
- final Collection<String> crossjoinEntitySetNames)
+ final Collection<String> crossjoinEntitySetNames, final Map<String, AliasQueryOption> aliases)
throws UriParserException, UriValidationException {
OrderByOptionImpl orderByOption = new OrderByOptionImpl();
do {
final Expression orderByExpression = new ExpressionParser(edm, odata)
- .parse(tokenizer, referencedType, crossjoinEntitySetNames);
+ .parse(tokenizer, referencedType, crossjoinEntitySetNames, aliases);
OrderByItemImpl item = new OrderByItemImpl();
item.setExpression(orderByExpression);
if (tokenizer.next(TokenKind.AscSuffix)) {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java
index 586cb10..e1313c1 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java
@@ -20,8 +20,10 @@ package org.apache.olingo.server.core.uri.parser;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import org.apache.olingo.commons.api.edm.Edm;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmStructuredType;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.ex.ODataRuntimeException;
@@ -36,21 +38,30 @@ import org.apache.olingo.server.api.uri.UriResourcePartTyped;
import org.apache.olingo.server.api.uri.UriResourceRef;
import org.apache.olingo.server.api.uri.UriResourceValue;
import org.apache.olingo.server.api.uri.queryoption.AliasQueryOption;
-import org.apache.olingo.server.api.uri.queryoption.CustomQueryOption;
+import org.apache.olingo.server.api.uri.queryoption.ExpandItem;
+import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
+import org.apache.olingo.server.api.uri.queryoption.FilterOption;
+import org.apache.olingo.server.api.uri.queryoption.OrderByItem;
+import org.apache.olingo.server.api.uri.queryoption.OrderByOption;
import org.apache.olingo.server.api.uri.queryoption.QueryOption;
+import org.apache.olingo.server.api.uri.queryoption.SelectOption;
import org.apache.olingo.server.api.uri.queryoption.SystemQueryOption;
import org.apache.olingo.server.api.uri.queryoption.SystemQueryOptionKind;
-import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
import org.apache.olingo.server.core.uri.UriInfoImpl;
import org.apache.olingo.server.core.uri.UriResourceStartingTypeFilterImpl;
import org.apache.olingo.server.core.uri.parser.UriTokenizer.TokenKind;
import org.apache.olingo.server.core.uri.parser.search.SearchParser;
import org.apache.olingo.server.core.uri.queryoption.AliasQueryOptionImpl;
import org.apache.olingo.server.core.uri.queryoption.CountOptionImpl;
+import org.apache.olingo.server.core.uri.queryoption.ExpandOptionImpl;
+import org.apache.olingo.server.core.uri.queryoption.FilterOptionImpl;
import org.apache.olingo.server.core.uri.queryoption.FormatOptionImpl;
import org.apache.olingo.server.core.uri.queryoption.IdOptionImpl;
+import org.apache.olingo.server.core.uri.queryoption.OrderByOptionImpl;
+import org.apache.olingo.server.core.uri.queryoption.SelectOptionImpl;
import org.apache.olingo.server.core.uri.queryoption.SkipOptionImpl;
import org.apache.olingo.server.core.uri.queryoption.SkipTokenOptionImpl;
+import org.apache.olingo.server.core.uri.queryoption.SystemQueryOptionImpl;
import org.apache.olingo.server.core.uri.queryoption.TopOptionImpl;
import org.apache.olingo.server.core.uri.validator.UriValidationException;
@@ -74,6 +85,32 @@ public class Parser {
throws UriParserException, UriValidationException {
UriInfoImpl contextUriInfo = new UriInfoImpl();
+
+ // Read the query options (system and custom options).
+ // This is done before parsing the resource path because the aliases have to be available there.
+ // System query options that can only be parsed with context from the resource path will be post-processed later.
+ final List<QueryOption> options =
+ query == null ? Collections.<QueryOption> emptyList() : UriDecoder.splitAndDecodeOptions(query);
+ for (final QueryOption option : options) {
+ final String optionName = option.getName();
+ // Parse the untyped option and retrieve a system-option or alias-option instance (or null for a custom option).
+ final QueryOption parsedOption = parseOption(optionName, option.getText());
+ try {
+ contextUriInfo.setQueryOption(parsedOption == null ? option : parsedOption);
+ } catch (final ODataRuntimeException e) {
+ throw new UriParserSyntaxException(
+ parsedOption instanceof SystemQueryOption ?
+ "Double system query option!" :
+ "Alias already specified! Name: " + optionName,
+ e,
+ parsedOption instanceof SystemQueryOption ?
+ UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION :
+ UriParserSyntaxException.MessageKeys.DUPLICATED_ALIAS,
+ optionName);
+ }
+ }
+
+ // Read the decoded path segments.
EdmType contextType = null;
boolean contextIsCollection = false;
@@ -85,7 +122,6 @@ public class Parser {
numberOfSegments--;
}
- // first, read the decoded path segments
final String firstSegment = pathSegmentsDecoded.get(0);
if (firstSegment.isEmpty()) {
@@ -107,24 +143,29 @@ public class Parser {
contextIsCollection = true;
} else if (firstSegment.equals("$entity")) {
+ contextUriInfo.setKind(UriInfoKind.entityId);
if (numberOfSegments > 1) {
final String typeCastSegment = pathSegmentsDecoded.get(1);
ensureLastSegment(typeCastSegment, 2, numberOfSegments);
- contextUriInfo = new ResourcePathParser(edm).parseDollarEntityTypeCast(typeCastSegment);
- contextType = contextUriInfo.getEntityTypeCast();
- } else {
- contextUriInfo.setKind(UriInfoKind.entityId);
+ contextType = new ResourcePathParser(edm, contextUriInfo.getAliasMap())
+ .parseDollarEntityTypeCast(typeCastSegment);
+ contextUriInfo.setEntityTypeCast((EdmEntityType) contextType);
}
contextIsCollection = false;
} else if (firstSegment.startsWith("$crossjoin")) {
ensureLastSegment(firstSegment, 1, numberOfSegments);
- contextUriInfo = new ResourcePathParser(edm).parseCrossjoinSegment(firstSegment);
+ contextUriInfo.setKind(UriInfoKind.crossjoin);
+ final List<String> entitySetNames = new ResourcePathParser(edm, contextUriInfo.getAliasMap())
+ .parseCrossjoinSegment(firstSegment);
+ for (final String name : entitySetNames) {
+ contextUriInfo.addEntitySetName(name);
+ }
contextIsCollection = true;
} else {
contextUriInfo.setKind(UriInfoKind.resource);
- final ResourcePathParser resourcePathParser = new ResourcePathParser(edm);
+ final ResourcePathParser resourcePathParser = new ResourcePathParser(edm, contextUriInfo.getAliasMap());
int count = 0;
UriResource lastSegment = null;
for (final String pathSegment : pathSegmentsDecoded) {
@@ -162,161 +203,168 @@ public class Parser {
}
}
- // second, read the system query options and the custom query options
- final List<QueryOption> options =
- query == null ? Collections.<QueryOption> emptyList() : UriDecoder.splitAndDecodeOptions(query);
- for (final QueryOption option : options) {
- final String optionName = option.getName();
- final String optionValue = option.getText();
- if (optionName.startsWith(DOLLAR)) {
- SystemQueryOption systemOption = null;
- if (optionName.equals(SystemQueryOptionKind.FILTER.toString())) {
- UriTokenizer filterTokenizer = new UriTokenizer(optionValue);
- // The referring type could be a primitive type or a structured type.
- systemOption = new FilterParser(edm, odata).parse(filterTokenizer,
- contextType,
- contextUriInfo.getEntitySetNames());
- checkOptionEOF(filterTokenizer, optionName, optionValue);
-
- } else if (optionName.equals(SystemQueryOptionKind.FORMAT.toString())) {
- FormatOptionImpl formatOption = new FormatOptionImpl();
- formatOption.setText(optionValue);
- if (optionValue.equalsIgnoreCase(JSON)
- || optionValue.equalsIgnoreCase(XML)
- || optionValue.equalsIgnoreCase(ATOM)
- || isFormatSyntaxValid(optionValue)) {
- formatOption.setFormat(optionValue);
- } else {
- throw new UriParserSyntaxException("Illegal value of $format option!",
- UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION_FORMAT, optionValue);
- }
- systemOption = formatOption;
-
- } else if (optionName.equals(SystemQueryOptionKind.EXPAND.toString())) {
- if (contextType instanceof EdmStructuredType
- || !contextUriInfo.getEntitySetNames().isEmpty()
- || contextUriInfo.getKind() == UriInfoKind.all) {
- UriTokenizer expandTokenizer = new UriTokenizer(optionValue);
- systemOption = new ExpandParser(edm, odata).parse(expandTokenizer,
- contextType instanceof EdmStructuredType ? (EdmStructuredType) contextType : null);
- checkOptionEOF(expandTokenizer, optionName, optionValue);
- } else {
- throw new UriValidationException("Expand is only allowed on structured types!",
- UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED, optionName);
- }
-
- } else if (optionName.equals(SystemQueryOptionKind.ID.toString())) {
- IdOptionImpl idOption = new IdOptionImpl();
- idOption.setText(optionValue);
- if (optionValue == null || optionValue.isEmpty()) {
- throw new UriParserSyntaxException("Illegal value of $id option!",
- UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION,
- optionName, optionValue);
- }
- idOption.setValue(optionValue);
- systemOption = idOption;
-
- } else if (optionName.equals(SystemQueryOptionKind.LEVELS.toString())) {
- throw new UriParserSyntaxException("System query option '$levels' is allowed only inside '$expand'!",
- UriParserSyntaxException.MessageKeys.SYSTEM_QUERY_OPTION_LEVELS_NOT_ALLOWED_HERE);
-
- } else if (optionName.equals(SystemQueryOptionKind.ORDERBY.toString())) {
- UriTokenizer orderByTokenizer = new UriTokenizer(optionValue);
- systemOption = new OrderByParser(edm, odata).parse(orderByTokenizer,
- contextType instanceof EdmStructuredType ? (EdmStructuredType) contextType : null,
- contextUriInfo.getEntitySetNames());
- checkOptionEOF(orderByTokenizer, optionName, optionValue);
-
- } else if (optionName.equals(SystemQueryOptionKind.SEARCH.toString())) {
- systemOption = new SearchParser().parse(optionValue);
-
- } else if (optionName.equals(SystemQueryOptionKind.SELECT.toString())) {
- UriTokenizer selectTokenizer = new UriTokenizer(optionValue);
- systemOption = new SelectParser(edm).parse(selectTokenizer,
- contextType instanceof EdmStructuredType ? (EdmStructuredType) contextType : null,
- contextIsCollection);
- checkOptionEOF(selectTokenizer, optionName, optionValue);
-
- } else if (optionName.equals(SystemQueryOptionKind.SKIP.toString())) {
- SkipOptionImpl skipOption = new SkipOptionImpl();
- skipOption.setText(optionValue);
- skipOption.setValue(ParserHelper.parseNonNegativeInteger(optionName, optionValue, true));
- systemOption = skipOption;
+ // Post-process system query options that need context information from the resource path.
+ parseFilterOption(contextUriInfo.getFilterOption(), contextType,
+ contextUriInfo.getEntitySetNames(), contextUriInfo.getAliasMap());
+ parseOrderByOption(contextUriInfo.getOrderByOption(), contextType,
+ contextUriInfo.getEntitySetNames(), contextUriInfo.getAliasMap());
+ parseExpandOption(contextUriInfo.getExpandOption(), contextType,
+ !contextUriInfo.getEntitySetNames().isEmpty() || contextUriInfo.getKind() == UriInfoKind.all,
+ contextUriInfo.getAliasMap());
+ parseSelectOption(contextUriInfo.getSelectOption(), contextType, contextIsCollection);
- } else if (optionName.equals(SystemQueryOptionKind.SKIPTOKEN.toString())) {
- SkipTokenOptionImpl skipTokenOption = new SkipTokenOptionImpl();
- skipTokenOption.setText(optionValue);
- if (optionValue == null || optionValue.isEmpty()) {
- throw new UriParserSyntaxException("Illegal value of $skiptoken option!",
- UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION,
- optionName, optionValue);
- }
- skipTokenOption.setValue(optionValue);
- systemOption = skipTokenOption;
-
- } else if (optionName.equals(SystemQueryOptionKind.TOP.toString())) {
- TopOptionImpl topOption = new TopOptionImpl();
- topOption.setText(optionValue);
- topOption.setValue(ParserHelper.parseNonNegativeInteger(optionName, optionValue, true));
- systemOption = topOption;
-
- } else if (optionName.equals(SystemQueryOptionKind.COUNT.toString())) {
- CountOptionImpl inlineCountOption = new CountOptionImpl();
- inlineCountOption.setText(optionValue);
- if (optionValue.equals("true") || optionValue.equals("false")) {
- inlineCountOption.setValue(Boolean.parseBoolean(optionValue));
- } else {
- throw new UriParserSyntaxException("Illegal value of $count option!",
- UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION,
- optionName, optionValue);
- }
- systemOption = inlineCountOption;
+ return contextUriInfo;
+ }
+ private QueryOption parseOption(final String optionName, final String optionValue)
+ throws UriParserException, UriValidationException {
+ if (optionName.startsWith(DOLLAR)) {
+ final SystemQueryOptionKind kind = SystemQueryOptionKind.get(optionName);
+ if (kind == null) {
+ throw new UriParserSyntaxException("Unknown system query option!",
+ UriParserSyntaxException.MessageKeys.UNKNOWN_SYSTEM_QUERY_OPTION, optionName);
+ }
+ SystemQueryOption systemOption = null;
+ switch (kind) {
+ case SEARCH:
+ systemOption = new SearchParser().parse(optionValue);
+ break;
+ case FILTER:
+ systemOption = new FilterOptionImpl();
+ break;
+ case COUNT:
+ if (optionValue.equals("true") || optionValue.equals("false")) {
+ systemOption = new CountOptionImpl().setValue(Boolean.parseBoolean(optionValue));
} else {
- throw new UriParserSyntaxException("Unknown system query option!",
- UriParserSyntaxException.MessageKeys.UNKNOWN_SYSTEM_QUERY_OPTION, optionName);
+ throw new UriParserSyntaxException("Illegal value of $count option!",
+ UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION,
+ optionName, optionValue);
}
- try {
- contextUriInfo.setSystemQueryOption(systemOption);
- } catch (final ODataRuntimeException e) {
- throw new UriParserSyntaxException("Double system query option!", e,
- UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION, optionName);
+ break;
+ case ORDERBY:
+ systemOption = new OrderByOptionImpl();
+ break;
+ case SKIP:
+ systemOption = new SkipOptionImpl()
+ .setValue(ParserHelper.parseNonNegativeInteger(optionName, optionValue, true));
+ break;
+ case SKIPTOKEN:
+ if (optionValue.isEmpty()) {
+ throw new UriParserSyntaxException("Illegal value of $skiptoken option!",
+ UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION,
+ optionName, optionValue);
}
-
- } else if (optionName.startsWith(AT)) {
- if (contextUriInfo.getAlias(optionName) == null) {
- // TODO: Aliases can only be parsed in the context of their usage.
- Expression expression = null;
- UriTokenizer aliasTokenizer = new UriTokenizer(optionValue);
- if (aliasTokenizer.next(TokenKind.jsonArrayOrObject)) {
- if (!aliasTokenizer.next(TokenKind.EOF)) {
- throw new UriParserSyntaxException("Illegal value for alias '" + optionName + "'.",
- UriParserSyntaxException.MessageKeys.SYNTAX);
- }
- } else {
- UriTokenizer aliasValueTokenizer = new UriTokenizer(optionValue);
- expression = new ExpressionParser(edm, odata).parse(aliasValueTokenizer, null,
- contextUriInfo.getEntitySetNames());
- if (!aliasValueTokenizer.next(TokenKind.EOF)) {
- throw new UriParserSyntaxException("Illegal value for alias '" + optionName + "'.",
- UriParserSyntaxException.MessageKeys.SYNTAX);
- }
- }
- contextUriInfo.addAlias((AliasQueryOption) new AliasQueryOptionImpl()
- .setAliasValue(expression)
- .setName(optionName)
- .setText(NULL.equals(optionValue) ? null : optionValue));
+ systemOption = new SkipTokenOptionImpl().setValue(optionValue);
+ break;
+ case TOP:
+ systemOption = new TopOptionImpl()
+ .setValue(ParserHelper.parseNonNegativeInteger(optionName, optionValue, true));
+ break;
+ case EXPAND:
+ systemOption = new ExpandOptionImpl();
+ break;
+ case SELECT:
+ systemOption = new SelectOptionImpl();
+ break;
+ case FORMAT:
+ if (optionValue.equalsIgnoreCase(JSON)
+ || optionValue.equalsIgnoreCase(XML)
+ || optionValue.equalsIgnoreCase(ATOM)
+ || isFormatSyntaxValid(optionValue)) {
+ systemOption = new FormatOptionImpl().setFormat(optionValue);
} else {
- throw new UriParserSyntaxException("Alias already specified! Name: " + optionName,
- UriParserSyntaxException.MessageKeys.DUPLICATED_ALIAS, optionName);
+ throw new UriParserSyntaxException("Illegal value of $format option!",
+ UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION_FORMAT, optionValue);
}
+ break;
+ case ID:
+ if (optionValue.isEmpty()) {
+ throw new UriParserSyntaxException("Illegal value of $id option!",
+ UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION,
+ optionName, optionValue);
+ }
+ systemOption = new IdOptionImpl().setValue(optionValue);
+ break;
+ case LEVELS:
+ throw new UriParserSyntaxException("System query option '$levels' is allowed only inside '$expand'!",
+ UriParserSyntaxException.MessageKeys.SYSTEM_QUERY_OPTION_LEVELS_NOT_ALLOWED_HERE);
+ }
+ ((SystemQueryOptionImpl) systemOption).setText(optionValue);
+ return systemOption;
- } else if (!optionName.isEmpty()) {
- contextUriInfo.addCustomQueryOption((CustomQueryOption) option);
+ } else if (optionName.startsWith(AT)) {
+ // Aliases can only be parsed in the context of their usage, so the value is not checked here.
+ return new AliasQueryOptionImpl()
+ .setName(optionName)
+ .setText(NULL.equals(optionValue) ? null : optionValue);
+
+ } else {
+ // The option is a custom query option; the caller can re-use its query option.
+ return null;
+ }
+ }
+
+ private void parseFilterOption(FilterOption filterOption, final EdmType contextType,
+ final List<String> entitySetNames, final Map<String, AliasQueryOption> aliases)
+ throws UriParserException, UriValidationException {
+ if (filterOption != null) {
+ final String optionValue = filterOption.getText();
+ UriTokenizer filterTokenizer = new UriTokenizer(optionValue);
+ // The referring type could be a primitive type or a structured type.
+ ((FilterOptionImpl) filterOption).setExpression(
+ new FilterParser(edm, odata).parse(filterTokenizer, contextType, entitySetNames, aliases)
+ .getExpression());
+ checkOptionEOF(filterTokenizer, filterOption.getName(), optionValue);
+ }
+ }
+
+ private void parseOrderByOption(OrderByOption orderByOption, final EdmType contextType,
+ final List<String> entitySetNames, final Map<String, AliasQueryOption> aliases)
+ throws UriParserException, UriValidationException {
+ if (orderByOption != null) {
+ final String optionValue = orderByOption.getText();
+ UriTokenizer orderByTokenizer = new UriTokenizer(optionValue);
+ final OrderByOption option = new OrderByParser(edm, odata).parse(orderByTokenizer,
+ contextType instanceof EdmStructuredType ? (EdmStructuredType) contextType : null,
+ entitySetNames,
+ aliases);
+ checkOptionEOF(orderByTokenizer, orderByOption.getName(), optionValue);
+ for (final OrderByItem item : option.getOrders()) {
+ ((OrderByOptionImpl) orderByOption).addOrder(item);
}
}
+ }
- return contextUriInfo;
+ private void parseExpandOption(ExpandOption expandOption, final EdmType contextType, final boolean isCrossjoinOrAll,
+ final Map<String, AliasQueryOption> aliases) throws UriParserException, UriValidationException {
+ if (expandOption != null) {
+ if (!(contextType instanceof EdmStructuredType || isCrossjoinOrAll)) {
+ throw new UriValidationException("Expand is only allowed on structured types!",
+ UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED, expandOption.getName());
+ }
+ final String optionValue = expandOption.getText();
+ UriTokenizer expandTokenizer = new UriTokenizer(optionValue);
+ final ExpandOption option = new ExpandParser(edm, odata, aliases).parse(expandTokenizer,
+ contextType instanceof EdmStructuredType ? (EdmStructuredType) contextType : null);
+ checkOptionEOF(expandTokenizer, expandOption.getName(), optionValue);
+ for (final ExpandItem item : option.getExpandItems()) {
+ ((ExpandOptionImpl) expandOption).addExpandItem(item);
+ }
+ }
+ }
+
+ private void parseSelectOption(SelectOption selectOption, final EdmType contextType,
+ final boolean contextIsCollection) throws UriParserException, UriValidationException {
+ if (selectOption != null) {
+ final String optionValue = selectOption.getText();
+ UriTokenizer selectTokenizer = new UriTokenizer(optionValue);
+ ((SelectOptionImpl) selectOption).setSelectItems(
+ new SelectParser(edm).parse(selectTokenizer,
+ contextType instanceof EdmStructuredType ? (EdmStructuredType) contextType : null,
+ contextIsCollection)
+ .getSelectItems());
+ checkOptionEOF(selectTokenizer, selectOption.getName(), optionValue);
+ }
}
private void ensureLastSegment(final String segment, final int pos, final int size)
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ParserHelper.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ParserHelper.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ParserHelper.java
index b0c2972..9986542 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ParserHelper.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ParserHelper.java
@@ -20,6 +20,7 @@ package org.apache.olingo.server.core.uri.parser;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -27,8 +28,10 @@ import java.util.Map.Entry;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.edm.EdmFunction;
import org.apache.olingo.commons.api.edm.EdmKeyPropertyRef;
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
+import org.apache.olingo.commons.api.edm.EdmParameter;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
@@ -39,6 +42,7 @@ import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.uri.UriParameter;
import org.apache.olingo.server.api.uri.UriResourcePartTyped;
+import org.apache.olingo.server.api.uri.queryoption.AliasQueryOption;
import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
import org.apache.olingo.server.api.uri.queryoption.expression.Literal;
import org.apache.olingo.server.core.ODataImpl;
@@ -46,6 +50,8 @@ import org.apache.olingo.server.core.uri.UriParameterImpl;
import org.apache.olingo.server.core.uri.UriResourceTypedImpl;
import org.apache.olingo.server.core.uri.UriResourceWithKeysImpl;
import org.apache.olingo.server.core.uri.parser.UriTokenizer.TokenKind;
+import org.apache.olingo.server.core.uri.queryoption.AliasQueryOptionImpl;
+import org.apache.olingo.server.core.uri.queryoption.expression.LiteralImpl;
import org.apache.olingo.server.core.uri.validator.UriValidationException;
public class ParserHelper {
@@ -55,7 +61,7 @@ public class ParserHelper {
protected static final Map<TokenKind, EdmPrimitiveTypeKind> tokenToPrimitiveType;
static {
/* Enum and null are not present in the map. These have to be handled differently. */
- Map<TokenKind, EdmPrimitiveTypeKind> temp = new HashMap<TokenKind, EdmPrimitiveTypeKind>();
+ Map<TokenKind, EdmPrimitiveTypeKind> temp = new EnumMap<TokenKind, EdmPrimitiveTypeKind>(TokenKind.class);
temp.put(TokenKind.BooleanValue, EdmPrimitiveTypeKind.Boolean);
temp.put(TokenKind.StringValue, EdmPrimitiveTypeKind.String);
// Very large integer values are of type Edm.Decimal but this is handled elsewhere.
@@ -87,18 +93,18 @@ public class ParserHelper {
tokenToPrimitiveType = Collections.unmodifiableMap(temp);
}
- public static void requireNext(UriTokenizer tokenizer, final TokenKind required) throws UriParserException {
+ protected static void requireNext(UriTokenizer tokenizer, final TokenKind required) throws UriParserException {
if (!tokenizer.next(required)) {
throw new UriParserSyntaxException("Expected token '" + required.toString() + "' not found.",
UriParserSyntaxException.MessageKeys.SYNTAX);
}
}
- public static void requireTokenEnd(UriTokenizer tokenizer) throws UriParserException {
+ protected static void requireTokenEnd(UriTokenizer tokenizer) throws UriParserException {
requireNext(tokenizer, TokenKind.EOF);
}
- public static TokenKind next(UriTokenizer tokenizer, final TokenKind... kinds) {
+ protected static TokenKind next(UriTokenizer tokenizer, final TokenKind... kinds) {
for (final TokenKind kind : kinds) {
if (tokenizer.next(kind)) {
return kind;
@@ -107,7 +113,7 @@ public class ParserHelper {
return null;
}
- public static TokenKind nextPrimitiveValue(UriTokenizer tokenizer) {
+ protected static TokenKind nextPrimitiveValue(UriTokenizer tokenizer) {
return next(tokenizer,
TokenKind.NULL,
TokenKind.BooleanValue,
@@ -146,7 +152,8 @@ public class ParserHelper {
}
protected static List<UriParameter> parseFunctionParameters(UriTokenizer tokenizer,
- final Edm edm, final EdmType referringType, final boolean withComplex)
+ final Edm edm, final EdmType referringType, final boolean withComplex,
+ final Map<String, AliasQueryOption> aliases)
throws UriParserException, UriValidationException {
List<UriParameter> parameters = new ArrayList<UriParameter>();
ParserHelper.requireNext(tokenizer, TokenKind.OPEN);
@@ -164,40 +171,105 @@ public class ParserHelper {
if (tokenizer.next(TokenKind.COMMA) || tokenizer.next(TokenKind.CLOSE) || tokenizer.next(TokenKind.EOF)) {
throw new UriParserSyntaxException("Parameter value expected.", UriParserSyntaxException.MessageKeys.SYNTAX);
}
+ UriParameterImpl parameter = new UriParameterImpl().setName(name);
if (tokenizer.next(TokenKind.ParameterAliasName)) {
- parameters.add(new UriParameterImpl().setName(name).setAlias(tokenizer.getText()));
+ final String aliasName = tokenizer.getText();
+ parameter.setAlias(aliasName)
+ .setExpression(aliases.containsKey(aliasName) ? aliases.get(aliasName).getValue() : null);
} else if (tokenizer.next(TokenKind.jsonArrayOrObject)) {
if (withComplex) {
- parameters.add(new UriParameterImpl().setName(name).setText(tokenizer.getText()));
+ parameter.setText(tokenizer.getText());
} else {
throw new UriParserSemanticException("A JSON array or object is not allowed as parameter value.",
UriParserSemanticException.MessageKeys.COMPLEX_PARAMETER_IN_RESOURCE_PATH, tokenizer.getText());
}
} else if (withComplex) {
- final Expression expression = new ExpressionParser(edm, odata).parse(tokenizer, referringType, null);
- parameters.add(new UriParameterImpl().setName(name)
- .setText(expression instanceof Literal ?
- "null".equals(((Literal) expression).getText()) ? null : ((Literal) expression).getText() :
- null)
- .setExpression(expression instanceof Literal ? null : expression));
+ final Expression expression = new ExpressionParser(edm, odata).parse(tokenizer, referringType, null, aliases);
+ parameter.setText(expression instanceof Literal ?
+ "null".equals(((Literal) expression).getText()) ? null : ((Literal) expression).getText() :
+ null)
+ .setExpression(expression instanceof Literal ? null : expression);
} else if (nextPrimitiveValue(tokenizer) == null) {
throw new UriParserSemanticException("Wrong parameter value.",
UriParserSemanticException.MessageKeys.INVALID_KEY_VALUE, "");
} else {
final String literalValue = tokenizer.getText();
- parameters.add(new UriParameterImpl().setName(name)
- .setText("null".equals(literalValue) ? null : literalValue));
+ parameter.setText("null".equals(literalValue) ? null : literalValue);
}
+ parameters.add(parameter);
} while (tokenizer.next(TokenKind.COMMA));
ParserHelper.requireNext(tokenizer, TokenKind.CLOSE);
return parameters;
}
+ protected static void validateFunctionParameters(final EdmFunction function, final List<UriParameter> parameters,
+ final Edm edm, final EdmType referringType, final Map<String, AliasQueryOption> aliases)
+ throws UriParserException, UriValidationException {
+ for (final UriParameter parameter : parameters) {
+ final String parameterName = parameter.getName();
+ final EdmParameter edmParameter = function.getParameter(parameterName);
+ final boolean isNullable = edmParameter.isNullable();
+ if (parameter.getText() == null && parameter.getExpression() == null && !isNullable) {
+ if (parameter.getAlias() == null) {
+ // No alias, value is explicitly null.
+ throw new UriValidationException("Missing non-nullable parameter " + parameterName,
+ UriValidationException.MessageKeys.MISSING_PARAMETER, parameterName);
+ } else {
+ final String valueForAlias = aliases.containsKey(parameter.getAlias()) ?
+ parseAliasValue(parameter.getAlias(),
+ edmParameter.getType(), edmParameter.isNullable(), edmParameter.isCollection(),
+ edm, referringType, aliases).getText() :
+ null;
+ // Alias value is missing or explicitly null.
+ if (valueForAlias == null) {
+ throw new UriValidationException("Missing alias for " + parameterName,
+ UriValidationException.MessageKeys.MISSING_ALIAS, parameter.getAlias());
+ }
+ }
+ }
+ }
+ }
+
+ protected static AliasQueryOption parseAliasValue(final String name, final EdmType type, final boolean isNullable,
+ final boolean isCollection, final Edm edm, final EdmType referringType,
+ final Map<String, AliasQueryOption> aliases) throws UriParserException, UriValidationException {
+ final EdmTypeKind kind = type == null ? null : type.getKind();
+ final AliasQueryOption alias = aliases.get(name);
+ if (alias != null && alias.getText() != null) {
+ UriTokenizer aliasTokenizer = new UriTokenizer(alias.getText());
+ if (kind == null
+ || !((isCollection || kind == EdmTypeKind.COMPLEX || kind == EdmTypeKind.ENTITY ?
+ aliasTokenizer.next(TokenKind.jsonArrayOrObject) :
+ nextPrimitiveTypeValue(aliasTokenizer, (EdmPrimitiveType) type, isNullable))
+ && aliasTokenizer.next(TokenKind.EOF))) {
+ // The alias value is not an allowed literal value, so parse it again as expression.
+ aliasTokenizer = new UriTokenizer(alias.getText());
+ // Don't pass on the current alias to avoid circular references.
+ Map<String, AliasQueryOption> aliasesInner = new HashMap<String, AliasQueryOption>(aliases);
+ aliasesInner.remove(name);
+ final Expression expression = new ExpressionParser(edm, odata)
+ .parse(aliasTokenizer, referringType, null, aliasesInner);
+ final EdmType expressionType = ExpressionParser.getType(expression);
+ if (aliasTokenizer.next(TokenKind.EOF)
+ && (expressionType == null || type == null || expressionType.equals(type))) {
+ ((AliasQueryOptionImpl) alias).setAliasValue(expression);
+ } else {
+ throw new UriParserSemanticException("Illegal value for alias '" + alias.getName() + "'.",
+ UriParserSemanticException.MessageKeys.UNKNOWN_PART, alias.getText());
+ }
+ }
+ }
+ return alias;
+ }
+
protected static List<UriParameter> parseNavigationKeyPredicate(UriTokenizer tokenizer,
- final EdmNavigationProperty navigationProperty) throws UriParserException, UriValidationException {
+ final EdmNavigationProperty navigationProperty,
+ final Edm edm, final EdmType referringType, final Map<String, AliasQueryOption> aliases)
+ throws UriParserException, UriValidationException {
if (tokenizer.next(TokenKind.OPEN)) {
if (navigationProperty.isCollection()) {
- return parseKeyPredicate(tokenizer, navigationProperty.getType(), navigationProperty.getPartner());
+ return parseKeyPredicate(tokenizer, navigationProperty.getType(), navigationProperty.getPartner(),
+ edm, referringType, aliases);
} else {
throw new UriParserSemanticException("A key is not allowed on non-collection navigation properties.",
UriParserSemanticException.MessageKeys.KEY_NOT_ALLOWED);
@@ -207,7 +279,9 @@ public class ParserHelper {
}
protected static List<UriParameter> parseKeyPredicate(UriTokenizer tokenizer, final EdmEntityType edmEntityType,
- final EdmNavigationProperty partner) throws UriParserException, UriValidationException {
+ final EdmNavigationProperty partner,
+ final Edm edm, final EdmType referringType, final Map<String, AliasQueryOption> aliases)
+ throws UriParserException, UriValidationException {
final List<EdmKeyPropertyRef> keyPropertyRefs = edmEntityType.getKeyPropertyRefs();
if (tokenizer.next(TokenKind.CLOSE)) {
throw new UriParserSemanticException(
@@ -229,11 +303,11 @@ public class ParserHelper {
}
if (tokenizer.next(TokenKind.ODataIdentifier)) {
- keys.addAll(compoundKey(tokenizer, edmEntityType));
+ keys.addAll(compoundKey(tokenizer, edmEntityType, edm, referringType, aliases));
} else if (keyPropertyRefs.size() - referencedNames.size() == 1) {
for (final EdmKeyPropertyRef candidate : keyPropertyRefs) {
if (referencedNames.get(candidate.getName()) == null) {
- keys.add(simpleKey(tokenizer, candidate));
+ keys.add(simpleKey(tokenizer, candidate, edm, referringType, aliases));
break;
}
}
@@ -271,7 +345,8 @@ public class ParserHelper {
}
}
- private static UriParameter simpleKey(UriTokenizer tokenizer, final EdmKeyPropertyRef edmKeyPropertyRef)
+ private static UriParameter simpleKey(UriTokenizer tokenizer, final EdmKeyPropertyRef edmKeyPropertyRef,
+ final Edm edm, final EdmType referringType, final Map<String, AliasQueryOption> aliases)
throws UriParserException, UriValidationException {
final EdmProperty edmProperty = edmKeyPropertyRef == null ? null : edmKeyPropertyRef.getProperty();
if (nextPrimitiveTypeValue(tokenizer,
@@ -279,14 +354,15 @@ public class ParserHelper {
edmProperty == null ? false : edmProperty.isNullable())) {
final String literalValue = tokenizer.getText();
ParserHelper.requireNext(tokenizer, TokenKind.CLOSE);
- return createUriParameter(edmProperty, edmKeyPropertyRef.getName(), literalValue);
+ return createUriParameter(edmProperty, edmKeyPropertyRef.getName(), literalValue, edm, referringType, aliases);
} else {
throw new UriParserSemanticException("The key value is not valid.",
UriParserSemanticException.MessageKeys.INVALID_KEY_VALUE, edmKeyPropertyRef.getName());
}
}
- private static List<UriParameter> compoundKey(UriTokenizer tokenizer, final EdmEntityType edmEntityType)
+ private static List<UriParameter> compoundKey(UriTokenizer tokenizer, final EdmEntityType edmEntityType,
+ final Edm edm, final EdmType referringType, final Map<String, AliasQueryOption> aliases)
throws UriParserException, UriValidationException {
List<UriParameter> parameters = new ArrayList<UriParameter>();
@@ -312,7 +388,7 @@ public class ParserHelper {
throw new UriValidationException("Unknown key property " + keyPredicateName,
UriValidationException.MessageKeys.INVALID_KEY_PROPERTY, keyPredicateName);
}
- parameters.add(keyValuePair(tokenizer, keyPredicateName, edmEntityType));
+ parameters.add(keyValuePair(tokenizer, keyPredicateName, edmEntityType, edm, referringType, aliases));
parameterNames.add(keyPredicateName);
hasComma = tokenizer.next(TokenKind.COMMA);
if (hasComma) {
@@ -324,8 +400,9 @@ public class ParserHelper {
return parameters;
}
- protected static UriParameter keyValuePair(UriTokenizer tokenizer,
- final String keyPredicateName, final EdmEntityType edmEntityType)
+ private static UriParameter keyValuePair(UriTokenizer tokenizer,
+ final String keyPredicateName, final EdmEntityType edmEntityType,
+ final Edm edm, final EdmType referringType, final Map<String, AliasQueryOption> aliases)
throws UriParserException, UriValidationException {
final EdmKeyPropertyRef keyPropertyRef = edmEntityType.getKeyPropertyRef(keyPredicateName);
final EdmProperty edmProperty = keyPropertyRef == null ? null : keyPropertyRef.getProperty();
@@ -338,7 +415,7 @@ public class ParserHelper {
throw new UriParserSyntaxException("Key value expected.", UriParserSyntaxException.MessageKeys.SYNTAX);
}
if (nextPrimitiveTypeValue(tokenizer, (EdmPrimitiveType) edmProperty.getType(), edmProperty.isNullable())) {
- return createUriParameter(edmProperty, keyPredicateName, tokenizer.getText());
+ return createUriParameter(edmProperty, keyPredicateName, tokenizer.getText(), edm, referringType, aliases);
} else {
throw new UriParserSemanticException(keyPredicateName + " has not a valid key value.",
UriParserSemanticException.MessageKeys.INVALID_KEY_VALUE, keyPredicateName);
@@ -346,28 +423,43 @@ public class ParserHelper {
}
private static UriParameter createUriParameter(final EdmProperty edmProperty, final String parameterName,
- final String literalValue) throws UriParserException, UriValidationException {
- if (literalValue.startsWith("@")) {
- return new UriParameterImpl()
- .setName(parameterName)
- .setAlias(literalValue);
- }
-
+ final String literalValue, final Edm edm, final EdmType referringType,
+ final Map<String, AliasQueryOption> aliases) throws UriParserException, UriValidationException {
+ final AliasQueryOption alias = literalValue.startsWith("@") ?
+ getKeyAlias(literalValue, edmProperty, edm, referringType, aliases) :
+ null;
+ final String value = alias == null ? literalValue : alias.getText();
final EdmPrimitiveType primitiveType = (EdmPrimitiveType) edmProperty.getType();
try {
- if (!(primitiveType.validate(primitiveType.fromUriLiteral(literalValue), edmProperty.isNullable(),
+ if (!(primitiveType.validate(primitiveType.fromUriLiteral(value), edmProperty.isNullable(),
edmProperty.getMaxLength(), edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode()))) {
throw new UriValidationException("Invalid key property",
UriValidationException.MessageKeys.INVALID_KEY_PROPERTY, parameterName);
}
} catch (final EdmPrimitiveTypeException e) {
- throw new UriValidationException("Invalid key property",
+ throw new UriValidationException("Invalid key property", e,
UriValidationException.MessageKeys.INVALID_KEY_PROPERTY, parameterName);
}
return new UriParameterImpl()
.setName(parameterName)
- .setText("null".equals(literalValue) ? null : literalValue);
+ .setText("null".equals(literalValue) ? null : literalValue)
+ .setAlias(alias == null ? null : literalValue)
+ .setExpression(alias == null ? null :
+ alias.getValue() == null ? new LiteralImpl(value, primitiveType) : alias.getValue());
+ }
+
+ private static AliasQueryOption getKeyAlias(final String name, final EdmProperty edmProperty,
+ final Edm edm, final EdmType referringType, final Map<String, AliasQueryOption> aliases)
+ throws UriParserException, UriValidationException {
+ if (aliases.containsKey(name)) {
+ return parseAliasValue(name,
+ edmProperty.getType(), edmProperty.isNullable(), edmProperty.isCollection(),
+ edm, referringType, aliases);
+ } else {
+ throw new UriValidationException("Alias '" + name + "' for key value not found.",
+ UriValidationException.MessageKeys.MISSING_ALIAS, name);
+ }
}
private static boolean nextPrimitiveTypeValue(UriTokenizer tokenizer,
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ResourcePathParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ResourcePathParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ResourcePathParser.java
index 87cb91a..8d6d52d 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ResourcePathParser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ResourcePathParser.java
@@ -18,7 +18,9 @@
*/
package org.apache.olingo.server.core.uri.parser;
+import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmAction;
@@ -35,11 +37,10 @@ import org.apache.olingo.commons.api.edm.EdmStructuredType;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
-import org.apache.olingo.server.api.uri.UriInfoKind;
import org.apache.olingo.server.api.uri.UriParameter;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourcePartTyped;
-import org.apache.olingo.server.core.uri.UriInfoImpl;
+import org.apache.olingo.server.api.uri.queryoption.AliasQueryOption;
import org.apache.olingo.server.core.uri.UriResourceActionImpl;
import org.apache.olingo.server.core.uri.UriResourceComplexPropertyImpl;
import org.apache.olingo.server.core.uri.UriResourceCountImpl;
@@ -59,10 +60,12 @@ public class ResourcePathParser {
private final Edm edm;
private final EdmEntityContainer edmEntityContainer;
+ private final Map<String, AliasQueryOption> aliases;
private UriTokenizer tokenizer;
- public ResourcePathParser(final Edm edm) {
+ public ResourcePathParser(final Edm edm, final Map<String, AliasQueryOption> aliases) {
this.edm = edm;
+ this.aliases = aliases;
edmEntityContainer = edm.getEntityContainer();
}
@@ -100,8 +103,7 @@ public class ResourcePathParser {
UriParserSyntaxException.MessageKeys.SYNTAX);
}
- public UriInfoImpl parseDollarEntityTypeCast(final String pathSegment) throws UriParserException {
- UriInfoImpl uriInfo = new UriInfoImpl().setKind(UriInfoKind.entityId);
+ public EdmEntityType parseDollarEntityTypeCast(final String pathSegment) throws UriParserException {
tokenizer = new UriTokenizer(pathSegment);
ParserHelper.requireNext(tokenizer, TokenKind.QualifiedName);
final String name = tokenizer.getText();
@@ -110,18 +112,16 @@ public class ResourcePathParser {
if (type == null) {
throw new UriParserSemanticException("Type '" + name + "' not found.",
UriParserSemanticException.MessageKeys.UNKNOWN_TYPE, name);
- } else {
- uriInfo.setEntityTypeCast(type);
}
- return uriInfo;
+ return type;
}
- public UriInfoImpl parseCrossjoinSegment(final String pathSegment) throws UriParserException {
- UriInfoImpl uriInfo = new UriInfoImpl().setKind(UriInfoKind.crossjoin);
+ public List<String> parseCrossjoinSegment(final String pathSegment) throws UriParserException {
tokenizer = new UriTokenizer(pathSegment);
ParserHelper.requireNext(tokenizer, TokenKind.CROSSJOIN);
ParserHelper.requireNext(tokenizer, TokenKind.OPEN);
// At least one entity-set name is mandatory. Try to fetch all.
+ List<String> entitySetNames = new ArrayList<String>();
do {
ParserHelper.requireNext(tokenizer, TokenKind.ODataIdentifier);
final String name = tokenizer.getText();
@@ -130,12 +130,12 @@ public class ResourcePathParser {
throw new UriParserSemanticException("Expected Entity Set Name.",
UriParserSemanticException.MessageKeys.UNKNOWN_PART, name);
} else {
- uriInfo.addEntitySetName(name);
+ entitySetNames.add(name);
}
} while (tokenizer.next(TokenKind.COMMA));
ParserHelper.requireNext(tokenizer, TokenKind.CLOSE);
ParserHelper.requireTokenEnd(tokenizer);
- return uriInfo;
+ return entitySetNames;
}
private UriResource ref(final UriResource previous) throws UriParserException {
@@ -180,7 +180,7 @@ public class ResourcePathParser {
if (tokenizer.next(TokenKind.OPEN)) {
final List<UriParameter> keyPredicates =
- ParserHelper.parseKeyPredicate(tokenizer, entitySetResource.getEntityType(), null);
+ ParserHelper.parseKeyPredicate(tokenizer, entitySetResource.getEntityType(), null, edm, null, aliases);
entitySetResource.setKeyPredicates(keyPredicates);
}
@@ -251,7 +251,8 @@ public class ResourcePathParser {
UriParserSemanticException.MessageKeys.PROPERTY_NOT_IN_TYPE,
structType.getFullQualifiedName().getFullQualifiedNameAsString(), name);
}
- List<UriParameter> keyPredicate = ParserHelper.parseNavigationKeyPredicate(tokenizer, navigationProperty);
+ List<UriParameter> keyPredicate =
+ ParserHelper.parseNavigationKeyPredicate(tokenizer, navigationProperty, edm, null, aliases);
ParserHelper.requireTokenEnd(tokenizer);
return new UriResourceNavigationPropertyImpl(navigationProperty)
.setKeyPredicates(keyPredicate);
@@ -320,7 +321,8 @@ public class ResourcePathParser {
((UriResourceWithKeysImpl) previousTyped).setEntryTypeFilter(type);
}
if (tokenizer.next(TokenKind.OPEN)) {
- final List<UriParameter> keys = ParserHelper.parseKeyPredicate(tokenizer, (EdmEntityType) type, null);
+ final List<UriParameter> keys =
+ ParserHelper.parseKeyPredicate(tokenizer, (EdmEntityType) type, null, edm, null, aliases);
if (previousTyped.isCollection()) {
((UriResourceWithKeysImpl) previousTyped).setKeyPredicates(keys);
} else {
@@ -359,7 +361,7 @@ public class ResourcePathParser {
private UriResource functionCall(final EdmFunctionImport edmFunctionImport,
final FullQualifiedName boundFunctionName, final FullQualifiedName bindingParameterTypeName,
final boolean isBindingParameterCollection) throws UriParserException, UriValidationException {
- final List<UriParameter> parameters = ParserHelper.parseFunctionParameters(tokenizer, edm, null, false);
+ final List<UriParameter> parameters = ParserHelper.parseFunctionParameters(tokenizer, edm, null, false, aliases);
final List<String> names = ParserHelper.getParameterNames(parameters);
EdmFunction function = null;
if (edmFunctionImport != null) {
@@ -379,13 +381,15 @@ public class ResourcePathParser {
UriParserSemanticException.MessageKeys.UNKNOWN_PART, boundFunctionName.getFullQualifiedNameAsString());
}
}
+ ParserHelper.validateFunctionParameters(function, parameters, edm, null, aliases);
UriResourceFunctionImpl resource = new UriResourceFunctionImpl(edmFunctionImport, function, parameters);
if (tokenizer.next(TokenKind.OPEN)) {
if (function.getReturnType() != null
&& function.getReturnType().getType().getKind() == EdmTypeKind.ENTITY
&& function.getReturnType().isCollection()) {
resource.setKeyPredicates(
- ParserHelper.parseKeyPredicate(tokenizer, (EdmEntityType) function.getReturnType().getType(), null));
+ ParserHelper.parseKeyPredicate(tokenizer,
+ (EdmEntityType) function.getReturnType().getType(), null, edm, null, aliases));
} else {
throw new UriParserSemanticException("A key is not allowed.",
UriParserSemanticException.MessageKeys.KEY_NOT_ALLOWED);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/SelectParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/SelectParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/SelectParser.java
index 00f3673..9ec29e3 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/SelectParser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/SelectParser.java
@@ -123,11 +123,17 @@ public class SelectParser {
}
private FullQualifiedName parseAllOperationsInSchema(UriTokenizer tokenizer) throws UriParserException {
- final String name = tokenizer.getText();
+ final String namespace = tokenizer.getText();
if (tokenizer.next(TokenKind.DOT)) {
if (tokenizer.next(TokenKind.STAR)) {
- // TODO: Validate the namespace without loading the whole schema.
- return new FullQualifiedName(name, tokenizer.getText());
+ // Validate the namespace. Currently a namespace from a non-default schema is not supported.
+ // There is no direct access to the namespace without loading the whole schema;
+ // however, the default entity container should always be there, so its access methods can be used.
+ if (edm.getEntityContainer(new FullQualifiedName(namespace, edm.getEntityContainer().getName())) == null) {
+ throw new UriParserSemanticException("Wrong namespace '" + namespace + "'.",
+ UriParserSemanticException.MessageKeys.UNKNOWN_PART, namespace);
+ }
+ return new FullQualifiedName(namespace, tokenizer.getText());
} else {
throw new UriParserSemanticException("Expected star after dot.",
UriParserSemanticException.MessageKeys.UNKNOWN_PART, "");
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriTokenizer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriTokenizer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriTokenizer.java
index 0504473..d218666 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriTokenizer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriTokenizer.java
@@ -1311,8 +1311,18 @@ public class UriTokenizer {
|| nextJsonArrayOrObject();
}
+ /**
+ * Moves past a JSON object member if found; otherwise leaves the index unchanged.
+ * @return whether a JSON object member has been found at the current index
+ */
private boolean nextJsonMember() {
- return nextJsonString() && nextCharacter(':') && nextJsonValue();
+ final int lastGoodIndex = index;
+ if (nextJsonString() && nextCharacter(':') && nextJsonValue()) {
+ return true;
+ } else {
+ index = lastGoodIndex;
+ return false;
+ }
}
/**
[16/22] olingo-odata4 git commit: OLINGO-825: Adding the support for
odata.type such that the extended entity and complex types are correctly
de-serilized
Posted by mi...@apache.org.
OLINGO-825: Adding the support for odata.type such that the extended entity and complex types are correctly de-serilized
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/b7005b77
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/b7005b77
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/b7005b77
Branch: refs/heads/OLINGO-832_StreamSerializerPoC
Commit: b7005b774f9172b00ee90773e2f32ed84a9597cd
Parents: 8468308
Author: Ramesh Reddy <ra...@jboss.org>
Authored: Mon Feb 8 15:41:32 2016 -0600
Committer: Ramesh Reddy <ra...@jboss.org>
Committed: Mon Feb 8 15:41:32 2016 -0600
----------------------------------------------------------------------
.../olingo/fit/tecsvc/client/BasicITCase.java | 34 ++++----
.../fit/tecsvc/client/BatchClientITCase.java | 8 +-
.../olingo/fit/tecsvc/client/BindingITCase.java | 10 +--
.../fit/tecsvc/client/DeepInsertITCase.java | 31 ++++----
.../tecsvc/client/FilterSystemQueryITCase.java | 4 +-
.../org/apache/olingo/server/api/OData.java | 10 +++
.../server/core/requests/ActionRequest.java | 2 +-
.../server/core/requests/DataRequest.java | 6 +-
.../olingo/server/example/TripPinDataModel.java | 2 +-
.../apache/olingo/server/core/ODataImpl.java | 13 +++
.../json/ODataJsonDeserializer.java | 77 +++++++++++++++++-
.../deserializer/xml/ODataXmlDeserializer.java | 84 ++++++++++++++++++--
.../AbstractODataDeserializerTest.java | 5 +-
.../ODataDeserializerEntityCollectionTest.java | 4 +-
...ataJsonDeserializerActionParametersTest.java | 2 +-
.../json/ODataJsonDeserializerEntityTest.java | 46 ++++++++++-
...DataXMLDeserializerActionParametersTest.java | 2 +-
.../xml/ODataXmlDeserializerTest.java | 43 +++++++++-
18 files changed, 320 insertions(+), 63 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java
index c8e4848..a45f548 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java
@@ -391,7 +391,7 @@ public class BasicITCase extends AbstractParamTecSvcITCase {
getFactory().newPrimitiveValueBuilder().buildString("Test")));
newEntity.getProperties().add(
getFactory().newComplexProperty("PropertyCompTwoPrim",
- getFactory().newComplexValue("CTTwoPrim")
+ getFactory().newComplexValue(SERVICE_NAMESPACE+".CTTwoPrim")
.add(getFactory().newPrimitiveProperty(
PROPERTY_INT16,
getFactory().newPrimitiveValueBuilder().buildInt16((short) 1)))
@@ -537,19 +537,19 @@ public class BasicITCase extends AbstractParamTecSvcITCase {
entity.getProperties().add(
getFactory().newCollectionProperty("CollPropertyComp",
- getFactory().newCollectionValue("CTPrimComp")
- .add(getFactory().newComplexValue("CTPrimComp")
+ getFactory().newCollectionValue(SERVICE_NAMESPACE+".CTPrimComp")
+ .add(getFactory().newComplexValue(SERVICE_NAMESPACE+".CTPrimComp")
.add(getFactory().newPrimitiveProperty(PROPERTY_INT16,
getFactory().newPrimitiveValueBuilder().buildInt16((short) 42)))
.add(getFactory().newComplexProperty(PROPERTY_COMP,
- getFactory().newComplexValue("CTAllPrim")
+ getFactory().newComplexValue(SERVICE_NAMESPACE+".CTAllPrim")
.add(getFactory().newPrimitiveProperty(PROPERTY_STRING,
getFactory().newPrimitiveValueBuilder().buildString("42"))))))
- .add(getFactory().newComplexValue("CTPrimComp")
+ .add(getFactory().newComplexValue(SERVICE_NAMESPACE+".CTPrimComp")
.add(getFactory().newPrimitiveProperty(PROPERTY_INT16,
getFactory().newPrimitiveValueBuilder().buildInt16((short) 43)))
.add(getFactory().newComplexProperty(PROPERTY_COMP,
- getFactory().newComplexValue("CTAllPrim")
+ getFactory().newComplexValue(SERVICE_NAMESPACE+".CTAllPrim")
.add(getFactory().newPrimitiveProperty(PROPERTY_STRING,
getFactory().newPrimitiveValueBuilder().buildString("43"))))))));
@@ -597,22 +597,24 @@ public class BasicITCase extends AbstractParamTecSvcITCase {
getFactory().newPrimitiveProperty(PROPERTY_STRING,
getFactory().newPrimitiveValueBuilder().buildString("Complex collection test")));
entity.getProperties().add(getFactory().newComplexProperty("PropertyCompTwoPrim",
- getFactory().newComplexValue("CTTwoPrim")
+ getFactory().newComplexValue(SERVICE_NAMESPACE+".CTTwoPrim")
.add(getFactory().newPrimitiveProperty(PROPERTY_INT16,
getFactory().newPrimitiveValueBuilder().buildInt16((short) 1)))
.add(getFactory().newPrimitiveProperty(PROPERTY_STRING,
getFactory().newPrimitiveValueBuilder().buildString("1")))));
entity.getProperties().add(getFactory().newCollectionProperty("CollPropertyComp",
- getFactory().newCollectionValue("CTPrimComp")
- .add(getFactory().newComplexValue("CTPrimComp")
+ getFactory().newCollectionValue(SERVICE_NAMESPACE+".CTPrimComp")
+ .add(getFactory().newComplexValue(SERVICE_NAMESPACE+".CTPrimComp")
.add(getFactory().newPrimitiveProperty(PROPERTY_INT16,
getFactory().newPrimitiveValueBuilder().buildInt16((short) 1)))
- .add(getFactory().newComplexProperty(PROPERTY_COMP, getFactory().newComplexValue("CTAllPrim")
+ .add(getFactory().newComplexProperty(PROPERTY_COMP,
+ getFactory().newComplexValue(SERVICE_NAMESPACE+".CTAllPrim")
.add(getFactory().newPrimitiveProperty(PROPERTY_STRING,
getFactory().newPrimitiveValueBuilder().buildString("1"))))))
- .add(getFactory().newComplexValue("CTPrimComp")
- .add(getFactory().newComplexProperty(PROPERTY_COMP, getFactory().newComplexValue("CTAllPrim")
+ .add(getFactory().newComplexValue(SERVICE_NAMESPACE+".CTPrimComp")
+ .add(getFactory().newComplexProperty(PROPERTY_COMP,
+ getFactory().newComplexValue(SERVICE_NAMESPACE+".CTAllPrim")
.add(getFactory().newPrimitiveProperty(PROPERTY_STRING,
getFactory().newPrimitiveValueBuilder().buildString("2")))
.add(getFactory().newPrimitiveProperty(PROPERTY_INT16,
@@ -789,7 +791,7 @@ public class BasicITCase extends AbstractParamTecSvcITCase {
factory.newCollectionValue("Edm.String").add(
factory.newPrimitiveValueBuilder().buildString("Single entry!"))));
entity.getProperties().add(factory.newComplexProperty(PROPERTY_COMP_ALL_PRIM,
- factory.newComplexValue("CTAllPrim")
+ factory.newComplexValue(SERVICE_NAMESPACE+".CTAllPrim")
.add(factory.newPrimitiveProperty(PROPERTY_STRING,
factory.newPrimitiveValueBuilder().buildString("Changed")))));
@@ -883,7 +885,7 @@ public class BasicITCase extends AbstractParamTecSvcITCase {
.newPrimitiveValueBuilder()
.buildString("Must not be null")));
entity.getProperties().add(factory.newComplexProperty("PropertyCompTwoPrim", factory.newComplexValue
- ("CTTwoPrim")
+ (SERVICE_NAMESPACE+".CTTwoPrim")
.add(factory.newPrimitiveProperty(PROPERTY_STRING, factory.newPrimitiveValueBuilder()
.buildString("Must not be null")))
.add(factory.newPrimitiveProperty(PROPERTY_INT16,
@@ -892,7 +894,7 @@ public class BasicITCase extends AbstractParamTecSvcITCase {
factory.newCollectionValue("Edm.String")
.add(factory.newPrimitiveValueBuilder().buildString("Single entry!"))));
entity.getProperties().add(factory.newComplexProperty(PROPERTY_COMP_ALL_PRIM,
- factory.newComplexValue("CTAllPrim").add(
+ factory.newComplexValue(SERVICE_NAMESPACE+".CTAllPrim").add(
factory.newPrimitiveProperty(PROPERTY_STRING,
factory.newPrimitiveValueBuilder().buildString("Changed")))));
@@ -1165,7 +1167,7 @@ public class BasicITCase extends AbstractParamTecSvcITCase {
final ODataPropertyUpdateRequest requestUpdate = getEdmEnabledClient().getCUDRequestFactory()
.getPropertyComplexValueUpdateRequest(uri, UpdateType.PATCH,
getFactory().newComplexProperty(PROPERTY_COMP_ALL_PRIM,
- getFactory().newComplexValue("CTAllPrim")
+ getFactory().newComplexValue(SERVICE_NAMESPACE+".CTAllPrim")
.add(getFactory().newPrimitiveProperty(PROPERTY_INT64,
getFactory().newPrimitiveValueBuilder().buildInt64(Long.MIN_VALUE)))
.add(getFactory().newPrimitiveProperty(PROPERTY_DECIMAL,
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java
index 273779c..913d9f9 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java
@@ -358,7 +358,7 @@ public class BatchClientITCase extends AbstractParamTecSvcITCase {
final BatchManager streamManager = request.payloadManager();
final ODataChangeset changeset = streamManager.addChangeset();
- final ClientEntity entityESAllPrim = getFactory().newEntity(new FullQualifiedName(SERVICE_NAMESPACE, "ESAllPrim"));
+ final ClientEntity entityESAllPrim = getFactory().newEntity(new FullQualifiedName(SERVICE_NAMESPACE, "ETAllPrim"));
entityESAllPrim.getProperties().add(getFactory().newPrimitiveProperty("PropertyDouble",
getFactory().newPrimitiveValueBuilder().buildDouble(3.1415)));
@@ -446,7 +446,7 @@ public class BatchClientITCase extends AbstractParamTecSvcITCase {
URI editLink = targetURI.build();
ClientObjectFactory factory = getFactory();
- ClientEntity postEntity = factory.newEntity(new FullQualifiedName(SERVICE_NAMESPACE, "ESAllPrim"));
+ ClientEntity postEntity = factory.newEntity(new FullQualifiedName(SERVICE_NAMESPACE, "ETAllPrim"));
postEntity.addLink(factory.newEntityNavigationLink("NavPropertyETTwoPrimOne", getClient().newURIBuilder
(SERVICE_URI)
.appendEntitySetSegment("ESTwoPrim")
@@ -467,7 +467,7 @@ public class BatchClientITCase extends AbstractParamTecSvcITCase {
targetURI = getClient().newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESAllPrim").appendKeySegment(0);
editLink = targetURI.build();
- ClientEntity patchEntity = factory.newEntity(new FullQualifiedName(SERVICE_NAMESPACE, "ESAllPrim"));
+ ClientEntity patchEntity = factory.newEntity(new FullQualifiedName(SERVICE_NAMESPACE, "ETAllPrim"));
patchEntity.setEditLink(editLink);
patchEntity.getProperties().add(factory.newPrimitiveProperty("PropertyDouble",
@@ -483,7 +483,7 @@ public class BatchClientITCase extends AbstractParamTecSvcITCase {
targetURI = getClient().newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESAllPrim").appendKeySegment(15);
editLink = targetURI.build();
- patchEntity = factory.newEntity(new FullQualifiedName(SERVICE_NAMESPACE, "ESAllPrim"));
+ patchEntity = factory.newEntity(new FullQualifiedName(SERVICE_NAMESPACE, "ETAllPrim"));
patchEntity.setEditLink(editLink);
patchEntity.getProperties().add(factory.newPrimitiveProperty("PropertyDouble",
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BindingITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BindingITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BindingITCase.java
index 25e9c13..9caab23 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BindingITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BindingITCase.java
@@ -50,10 +50,10 @@ public class BindingITCase extends AbstractParamTecSvcITCase {
private static final String ES_TWO_KEY_NAV = "ESTwoKeyNav";
private static final String ET_KEY_NAV_NAME = "ETKeyNav";
private static final FullQualifiedName ET_KEY_NAV = new FullQualifiedName(SERVICE_NAMESPACE, ET_KEY_NAV_NAME);
- private static final String CT_PRIM_COMP = "CTPrimComp";
- private static final String CT_TWO_PRIM = "CTTwoPrim";
- private static final String CT_ALL_PRIM = "CTAllPrim";
- private static final String CT_NAV_FIVE_PROP = "CTNavFiveProp";
+ private static final String CT_COMP_NAV = SERVICE_NAMESPACE+"."+"CTCompNav";
+ private static final String CT_TWO_PRIM = SERVICE_NAMESPACE+"."+"CTTwoPrim";
+ private static final String CT_ALL_PRIM = SERVICE_NAMESPACE+"."+"CTAllPrim";
+ private static final String CT_NAV_FIVE_PROP = SERVICE_NAMESPACE+"."+"CTNavFiveProp";
private static final String PROPERTY_INT16 = "PropertyInt16";
private static final String PROPERTY_STRING = "PropertyString";
private static final String PROPERTY_COMP_NAV = "PropertyCompNav";
@@ -92,7 +92,7 @@ public class BindingITCase extends AbstractParamTecSvcITCase {
42)))
.add(factory.newPrimitiveProperty(PROPERTY_STRING, factory.newPrimitiveValueBuilder().buildString("42")))));
entity.getProperties()
- .add(factory.newComplexProperty(PROPERTY_COMP_COMP_NAV, factory.newComplexValue(CT_PRIM_COMP)
+ .add(factory.newComplexProperty(PROPERTY_COMP_COMP_NAV, factory.newComplexValue(CT_COMP_NAV)
.add(factory.newPrimitiveProperty(PROPERTY_STRING, factory.newPrimitiveValueBuilder()
.buildString("42")))
.add(factory.newComplexProperty(PROPERTY_COMP_NAV, factory.newComplexValue(CT_NAV_FIVE_PROP)
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/DeepInsertITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/DeepInsertITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/DeepInsertITCase.java
index d8a467a..53cf52c 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/DeepInsertITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/DeepInsertITCase.java
@@ -64,11 +64,12 @@ public class DeepInsertITCase extends AbstractParamTecSvcITCase {
private static final String ET_TWO_KEY_NAV_NAME = "ETTwoKeyNav";
private static final FullQualifiedName ET_KEY_NAV = new FullQualifiedName(SERVICE_NAMESPACE, ET_KEY_NAV_NAME);
private static final FullQualifiedName ET_TWO_KEY_NAV = new FullQualifiedName(SERVICE_NAMESPACE, ET_TWO_KEY_NAV_NAME);
- private static final String CT_PRIM_COMP = "CTPrimComp";
- private static final String CT_TWO_PRIM = "CTTwoPrim";
- private static final String CT_ALL_PRIM = "CTAllPrim";
- private static final String CT_NAV_FIVE_PROP = "CTNavFiveProp";
- private static final String CT_BASE_PRIM_COMP_NAV = "CTBasePrimCompNav";
+ private static final String CT_PRIM_COMP = SERVICE_NAMESPACE+"."+"CTPrimComp";
+ private static final String CT_COMP_NAV = SERVICE_NAMESPACE+"."+"CTCompNav";
+ private static final String CT_TWO_PRIM = SERVICE_NAMESPACE+"."+"CTTwoPrim";
+ private static final String CT_ALL_PRIM = SERVICE_NAMESPACE+"."+"CTAllPrim";
+ private static final String CT_NAV_FIVE_PROP = SERVICE_NAMESPACE+"."+"CTNavFiveProp";
+ private static final String CT_BASE_PRIM_COMP_NAV = SERVICE_NAMESPACE+"."+"CTBasePrimCompNav";
private static final String PROPERTY_INT16 = "PropertyInt16";
private static final String PROPERTY_STRING = "PropertyString";
private static final String PROPERTY_COMP = "PropertyComp";
@@ -308,7 +309,7 @@ public class DeepInsertITCase extends AbstractParamTecSvcITCase {
factory.newPrimitiveValueBuilder().buildString("42")))));
entity.getProperties()
.add(factory.newComplexProperty(PROPERTY_COMP_COMP_NAV,
- factory.newComplexValue(CT_PRIM_COMP)
+ factory.newComplexValue(CT_COMP_NAV)
.add(factory.newPrimitiveProperty(PROPERTY_STRING,
factory.newPrimitiveValueBuilder().buildString("42")))
.add(factory.newComplexProperty(PROPERTY_COMP_NAV,
@@ -330,7 +331,7 @@ public class DeepInsertITCase extends AbstractParamTecSvcITCase {
factory.newPrimitiveValueBuilder().buildInt16((short) 430)))));
inlineEntitySingle.getProperties()
.add(factory.newComplexProperty(PROPERTY_COMP_NAV,
- factory.newComplexValue(CT_PRIM_COMP)
+ factory.newComplexValue(CT_BASE_PRIM_COMP_NAV)
.add(factory.newPrimitiveProperty(PROPERTY_INT16,
factory.newPrimitiveValueBuilder().buildInt16((short) 431)))));
inlineEntitySingle.getProperties()
@@ -351,7 +352,7 @@ public class DeepInsertITCase extends AbstractParamTecSvcITCase {
.add(factory.newPrimitiveProperty(PROPERTY_STRING, factory.newPrimitiveValueBuilder().buildString("44")));
inlineEntityCol1.getProperties()
.add(factory.newComplexProperty(PROPERTY_COMP_NAV,
- factory.newComplexValue(CT_PRIM_COMP)
+ factory.newComplexValue(CT_BASE_PRIM_COMP_NAV)
.add(factory.newPrimitiveProperty(PROPERTY_INT16,
factory.newPrimitiveValueBuilder().buildInt16((short) 441)))));
inlineEntityCol1.getProperties()
@@ -374,7 +375,7 @@ public class DeepInsertITCase extends AbstractParamTecSvcITCase {
.add(factory.newPrimitiveProperty(PROPERTY_STRING, factory.newPrimitiveValueBuilder().buildString("45")));
inlineEntityCol2.getProperties()
.add(factory.newComplexProperty(PROPERTY_COMP_NAV,
- factory.newComplexValue(CT_PRIM_COMP)
+ factory.newComplexValue(CT_BASE_PRIM_COMP_NAV)
.add(factory.newPrimitiveProperty(PROPERTY_INT16,
factory.newPrimitiveValueBuilder().buildInt16((short) 451)))));
inlineEntityCol2.getProperties()
@@ -538,7 +539,7 @@ public class DeepInsertITCase extends AbstractParamTecSvcITCase {
factory.newPrimitiveValueBuilder().buildString("42")))));
entity.getProperties()
.add(factory.newComplexProperty(PROPERTY_COMP_COMP_NAV,
- factory.newComplexValue(CT_PRIM_COMP)
+ factory.newComplexValue(CT_COMP_NAV)
.add(factory.newPrimitiveProperty(PROPERTY_STRING,
factory.newPrimitiveValueBuilder().buildString("42")))
.add(factory.newComplexProperty(PROPERTY_COMP_NAV,
@@ -580,7 +581,7 @@ public class DeepInsertITCase extends AbstractParamTecSvcITCase {
factory.newPrimitiveValueBuilder().buildString("431")))));
innerEntity.getProperties()
.add(factory.newComplexProperty(PROPERTY_COMP_COMP_NAV,
- factory.newComplexValue(CT_PRIM_COMP)
+ factory.newComplexValue(CT_COMP_NAV)
.add(factory.newPrimitiveProperty(PROPERTY_STRING,
factory.newPrimitiveValueBuilder().buildString("431")))
.add(factory.newComplexProperty(PROPERTY_COMP_NAV,
@@ -804,7 +805,7 @@ public class DeepInsertITCase extends AbstractParamTecSvcITCase {
factory.newPrimitiveValueBuilder().buildString("42")))));
entity.getProperties()
.add(factory.newComplexProperty(PROPERTY_COMP_COMP_NAV,
- factory.newComplexValue(CT_PRIM_COMP)
+ factory.newComplexValue(CT_COMP_NAV)
.add(factory.newPrimitiveProperty(PROPERTY_STRING,
factory.newPrimitiveValueBuilder().buildString("42")))
.add(factory.newComplexProperty(PROPERTY_COMP_NAV,
@@ -825,7 +826,7 @@ public class DeepInsertITCase extends AbstractParamTecSvcITCase {
factory.newPrimitiveValueBuilder().buildInt16((short) 43)))));
inlineEntitySingle.getProperties()
.add(factory.newComplexProperty(PROPERTY_COMP_NAV,
- factory.newComplexValue(CT_PRIM_COMP)
+ factory.newComplexValue(CT_BASE_PRIM_COMP_NAV)
.add(factory.newPrimitiveProperty(PROPERTY_INT16,
factory.newPrimitiveValueBuilder().buildInt16((short) 431)))));
inlineEntitySingle.getProperties()
@@ -846,7 +847,7 @@ public class DeepInsertITCase extends AbstractParamTecSvcITCase {
.add(factory.newPrimitiveProperty(PROPERTY_STRING, factory.newPrimitiveValueBuilder().buildString("44")));
inlineEntityCol1.getProperties()
.add(factory.newComplexProperty(PROPERTY_COMP_NAV,
- factory.newComplexValue(CT_PRIM_COMP)
+ factory.newComplexValue(CT_BASE_PRIM_COMP_NAV)
.add(factory.newPrimitiveProperty(PROPERTY_INT16,
factory.newPrimitiveValueBuilder().buildInt16((short) 441)))));
inlineEntityCol1.getProperties()
@@ -871,7 +872,7 @@ public class DeepInsertITCase extends AbstractParamTecSvcITCase {
factory.newPrimitiveValueBuilder().buildString("45")));
inlineEntityCol2.getProperties()
.add(factory.newComplexProperty(PROPERTY_COMP_NAV,
- factory.newComplexValue(CT_PRIM_COMP)
+ factory.newComplexValue(CT_BASE_PRIM_COMP_NAV)
.add(factory.newPrimitiveProperty(PROPERTY_INT16,
factory.newPrimitiveValueBuilder().buildInt16((short) 451)))));
inlineEntityCol2.getProperties()
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FilterSystemQueryITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FilterSystemQueryITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FilterSystemQueryITCase.java
index 6865a65..ca66db5 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FilterSystemQueryITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FilterSystemQueryITCase.java
@@ -911,14 +911,14 @@ public class FilterSystemQueryITCase extends AbstractParamTecSvcITCase {
getFactory().newPrimitiveValueBuilder().buildString("Test")));
newEntity.getProperties().add(
getFactory().newComplexProperty("PropertyCompAllPrim",
- getFactory().newComplexValue("CTAllPrim")
+ getFactory().newComplexValue(SERVICE_NAMESPACE+"."+"CTAllPrim")
.add(getFactory().newPrimitiveProperty(
"PropertyString",
getFactory().newPrimitiveValueBuilder().buildString("Test 3")))));
newEntity.getProperties().add(
getFactory().newComplexProperty("PropertyCompTwoPrim",
- getFactory().newComplexValue("CTTwoPrim")
+ getFactory().newComplexValue(SERVICE_NAMESPACE+"."+"CTTwoPrim")
.add(getFactory().newPrimitiveProperty(
"PropertyInt16",
getFactory().newPrimitiveValueBuilder().buildInt16((short) 1)))
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/lib/server-api/src/main/java/org/apache/olingo/server/api/OData.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/OData.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/OData.java
index 8e90c57..26f5f61 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/OData.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/OData.java
@@ -132,6 +132,16 @@ public abstract class OData {
public abstract ODataDeserializer createDeserializer(ContentType contentType) throws DeserializerException;
/**
+ * Creates a new deserializer object for reading content in the specified format.
+ * Deserializers are used in Processor implementations.
+ *
+ * @param contentType any content type supported by Olingo (XML, JSON ...)
+ * @param metadata ServiceMetada of the service
+ */
+ public abstract ODataDeserializer createDeserializer(ContentType contentType,
+ ServiceMetadata metadata) throws DeserializerException;
+
+ /**
* Creates a primitive-type instance.
* @param kind the kind of the primitive type
* @return an {@link EdmPrimitiveType} instance for the type kind
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/ActionRequest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/ActionRequest.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/ActionRequest.java
index 9ff4cde..501b110 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/ActionRequest.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/ActionRequest.java
@@ -145,7 +145,7 @@ public class ActionRequest extends OperationRequest {
}
public List<Parameter> getParameters() throws DeserializerException {
- ODataDeserializer deserializer = odata.createDeserializer(getRequestContentType());
+ ODataDeserializer deserializer = odata.createDeserializer(getRequestContentType(), this.serviceMetadata);
return new ArrayList<Parameter>(deserializer.actionParameters(getPayload(), getAction()).getActionParameters()
.values());
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java
index 44c45bf..42fbdea 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java
@@ -333,7 +333,7 @@ public class DataRequest extends ServiceRequest {
}
private Entity getEntityFromClient() throws DeserializerException {
- ODataDeserializer deserializer = odata.createDeserializer(getRequestContentType());
+ ODataDeserializer deserializer = odata.createDeserializer(getRequestContentType(), getServiceMetaData());
return deserializer.entity(getODataRequest().getBody(), getEntitySet().getEntityType()).getEntity();
}
@@ -460,7 +460,7 @@ public class DataRequest extends ServiceRequest {
// /odata-json-format-v4.0-errata02-os-complete.html#_Toc403940643
// The below code reads as property and converts to an URI
private List<URI> getPayload() throws DeserializerException {
- ODataDeserializer deserializer = odata.createDeserializer(getRequestContentType());
+ ODataDeserializer deserializer = odata.createDeserializer(getRequestContentType(), getServiceMetaData());
return deserializer.entityReferences(getODataRequest().getBody()).getEntityReferences();
}
@@ -701,7 +701,7 @@ public class DataRequest extends ServiceRequest {
private org.apache.olingo.commons.api.data.Property getPropertyValueFromClient(
EdmProperty edmProperty) throws DeserializerException {
- ODataDeserializer deserializer = odata.createDeserializer(getRequestContentType());
+ ODataDeserializer deserializer = odata.createDeserializer(getRequestContentType(), getServiceMetaData());
return deserializer.property(getODataRequest().getBody(), edmProperty).getProperty();
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinDataModel.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinDataModel.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinDataModel.java
index c58d9ce..562eac0 100644
--- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinDataModel.java
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinDataModel.java
@@ -116,7 +116,7 @@ public class TripPinDataModel {
private EntityCollection loadEnities(String entitySetName, EdmEntityType type) {
try {
- ODataJsonDeserializer deserializer = new ODataJsonDeserializer(ContentType.JSON);
+ ODataJsonDeserializer deserializer = new ODataJsonDeserializer(ContentType.JSON, this.metadata);
EntityCollection set = deserializer.entityCollection(new FileInputStream(new File(
"src/test/resources/" + entitySetName.toLowerCase() + ".json")), type).getEntityCollection();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java
index 4c2642c..e5c5437 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java
@@ -121,6 +121,19 @@ public class ODataImpl extends OData {
throw new DeserializerException("Unsupported format: " + contentType.toContentTypeString(),
DeserializerException.MessageKeys.UNSUPPORTED_FORMAT, contentType.toContentTypeString());
}
+ }
+ @Override
+ public ODataDeserializer createDeserializer(final ContentType contentType,
+ ServiceMetadata metadata) throws DeserializerException {
+ if (contentType.isCompatible(ContentType.JSON)) {
+ return new ODataJsonDeserializer(contentType, metadata);
+ } else if (contentType.isCompatible(ContentType.APPLICATION_XML)
+ || contentType.isCompatible(ContentType.APPLICATION_ATOM_XML)) {
+ return new ODataXmlDeserializer(metadata);
+ } else {
+ throw new DeserializerException("Unsupported format: " + contentType.toContentTypeString(),
+ DeserializerException.MessageKeys.UNSUPPORTED_FORMAT, contentType.toContentTypeString());
+ }
}
@Override
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java
index 7bbc4a0..da57309 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java
@@ -48,10 +48,13 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.EdmProperty;
+import org.apache.olingo.commons.api.edm.EdmStructuredType;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.edm.EdmTypeDefinition;
+import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.deserializer.DeserializerException;
import org.apache.olingo.server.api.deserializer.DeserializerException.MessageKeys;
import org.apache.olingo.server.api.deserializer.DeserializerResult;
@@ -76,10 +79,20 @@ public class ODataJsonDeserializer implements ODataDeserializer {
private static final String ODATA_CONTROL_INFORMATION_PREFIX = "@odata.";
private final boolean isIEEE754Compatible;
+ private ServiceMetadata serviceMetadata;
public ODataJsonDeserializer(final ContentType contentType) {
isIEEE754Compatible = isODataIEEE754Compatible(contentType);
}
+
+ public ODataJsonDeserializer(final ContentType contentType, final ServiceMetadata serviceMetadata) {
+ isIEEE754Compatible = isODataIEEE754Compatible(contentType);
+ this.serviceMetadata = serviceMetadata;
+ }
+
+ public void setMetadata(ServiceMetadata metadata) {
+ this.serviceMetadata = metadata;
+ }
@Override
public DeserializerResult entityCollection(final InputStream stream, final EdmEntityType edmEntityType)
@@ -124,7 +137,8 @@ public class ODataJsonDeserializer implements ODataDeserializer {
throw new DeserializerException("Nested Arrays and primitive values are not allowed for an entity value.",
DeserializerException.MessageKeys.INVALID_ENTITY);
}
- entities.add(consumeEntityNode(edmEntityType, (ObjectNode) arrayElement, expandBuilder));
+ EdmEntityType derivedEdmEntityType = (EdmEntityType)getDerivedType(edmEntityType, arrayElement);
+ entities.add(consumeEntityNode(derivedEdmEntityType, (ObjectNode) arrayElement, expandBuilder));
}
return entities;
} else {
@@ -140,7 +154,9 @@ public class ODataJsonDeserializer implements ODataDeserializer {
final ObjectNode tree = parseJsonTree(stream);
final ExpandTreeBuilderImpl expandBuilder = new ExpandTreeBuilderImpl();
- return DeserializerResultImpl.with().entity(consumeEntityNode(edmEntityType, tree, expandBuilder))
+ EdmEntityType derivedEdmEntityType = (EdmEntityType)getDerivedType(edmEntityType, tree);
+
+ return DeserializerResultImpl.with().entity(consumeEntityNode(derivedEdmEntityType, tree, expandBuilder))
.expandOption(expandBuilder.build())
.build();
} catch (final IOException e) {
@@ -257,6 +273,7 @@ public class ODataJsonDeserializer implements ODataDeserializer {
edmParameter.isNullable(), edmParameter.getMaxLength(),
edmParameter.getPrecision(), edmParameter.getScale(), true, edmParameter.getMapping(), node);
parameter.setValue(property.getValueType(), property.getValue());
+ parameter.setType(property.getType());
}
return parameter;
}
@@ -472,7 +489,12 @@ public class ODataJsonDeserializer implements ODataDeserializer {
value);
break;
case COMPLEX:
- value = readComplexNode(name, type, isNullable, jsonNode);
+ EdmType derivedType = getDerivedType((EdmComplexType) type,
+ jsonNode);
+ property.setType(derivedType.getFullQualifiedName()
+ .getFullQualifiedNameAsString());
+
+ value = readComplexNode(name, derivedType, isNullable, jsonNode);
property.setValue(ValueType.COMPLEX, value);
break;
default:
@@ -808,4 +830,53 @@ public class ODataJsonDeserializer implements ODataDeserializer {
&& Boolean.TRUE.toString().equalsIgnoreCase(
contentType.getParameter(ContentType.PARAMETER_IEEE754_COMPATIBLE));
}
+
+ private EdmType getDerivedType(final EdmStructuredType edmType, final JsonNode jsonNode)
+ throws DeserializerException {
+ JsonNode odataTypeNode = jsonNode.get(Constants.JSON_TYPE);
+ if (odataTypeNode != null) {
+ String odataType = odataTypeNode.asText();
+ if (!odataType.isEmpty()) {
+ odataType = odataType.substring(1);
+
+ if (odataType.equalsIgnoreCase(edmType.getFullQualifiedName().getFullQualifiedNameAsString())) {
+ return edmType;
+ } else if (this.serviceMetadata == null) {
+ throw new DeserializerException(
+ "Failed to resolve Odata type " + odataType + " due to metadata is not available",
+ DeserializerException.MessageKeys.UNKNOWN_CONTENT);
+ }
+
+ EdmStructuredType currentEdmType = null;
+ if(edmType instanceof EdmEntityType) {
+ currentEdmType = serviceMetadata.getEdm()
+ .getEntityType(new FullQualifiedName(odataType));
+ } else {
+ currentEdmType = serviceMetadata.getEdm()
+ .getComplexType(new FullQualifiedName(odataType));
+ }
+ if (!isAssignable(edmType, currentEdmType)) {
+ throw new DeserializerException(
+ "Odata type " + odataType + " not allowed here",
+ DeserializerException.MessageKeys.UNKNOWN_CONTENT);
+ }
+
+ return currentEdmType;
+ }
+ }
+ return edmType;
+ }
+
+ private boolean isAssignable(final EdmStructuredType edmStructuredType,
+ final EdmStructuredType edmStructuredTypeToAssign) {
+ if (edmStructuredTypeToAssign == null) {
+ return false;
+ } else if (edmStructuredType.getFullQualifiedName()
+ .equals(edmStructuredTypeToAssign.getFullQualifiedName())) {
+ return true;
+ } else {
+ return isAssignable(edmStructuredType,
+ edmStructuredTypeToAssign.getBaseType());
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializer.java
index b556d8e..c8b5f96 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializer.java
@@ -52,10 +52,13 @@ import org.apache.olingo.commons.api.edm.EdmParameter;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.EdmProperty;
+import org.apache.olingo.commons.api.edm.EdmStructuredType;
import org.apache.olingo.commons.api.edm.EdmType;
+import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.core.edm.EdmTypeInfo;
import org.apache.olingo.commons.core.edm.primitivetype.AbstractGeospatialType;
+import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.deserializer.DeserializerException;
import org.apache.olingo.server.api.deserializer.DeserializerException.MessageKeys;
import org.apache.olingo.server.api.deserializer.DeserializerResult;
@@ -75,7 +78,21 @@ public class ODataXmlDeserializer implements ODataDeserializer {
private static final QName etagQName = new QName(Constants.NS_METADATA, Constants.ATOM_ATTR_ETAG);
private static final QName countQName = new QName(Constants.NS_METADATA, Constants.ATOM_ELEM_COUNT);
private static final QName parametersQName = new QName(Constants.NS_METADATA, "parameters");
+ private static final QName typeQName = new QName(Constants.NS_METADATA, Constants.ATTR_TYPE);
+
+ private ServiceMetadata serviceMetadata;
+ public ODataXmlDeserializer() {
+ }
+
+ public ODataXmlDeserializer(final ServiceMetadata serviceMetadata) {
+ this.serviceMetadata = serviceMetadata;
+ }
+
+ public void setMetadata(ServiceMetadata metadata) {
+ this.serviceMetadata = metadata;
+ }
+
protected XMLEventReader getReader(final InputStream input) throws XMLStreamException {
return FACTORY.createXMLEventReader(input);
}
@@ -178,7 +195,17 @@ public class ODataXmlDeserializer implements ODataDeserializer {
} else {
property.setName(start.getName().getLocalPart());
}
- valuable(property, reader, start, edmType, isNullable, maxLength, precision, scale, isUnicode, isCollection);
+
+ EdmType resolvedType = edmType;
+ final Attribute attrType = start.getAttributeByName(typeQName);
+ if (attrType != null && (edmType instanceof EdmComplexType)) {
+ String type = new EdmTypeInfo.Builder().setTypeExpression(attrType.getValue()).build().internal();
+ if (type.startsWith("Collection(") && type.endsWith(")")) {
+ type = type.substring(11, type.length()-1);
+ }
+ resolvedType = getDerivedType((EdmComplexType)edmType, type);
+ }
+ valuable(property, reader, start, resolvedType, isNullable, maxLength, precision, scale, isUnicode, isCollection);
return property;
}
@@ -431,6 +458,7 @@ public class ODataXmlDeserializer implements ODataDeserializer {
private Entity entity(final XMLEventReader reader, final StartElement start, final EdmEntityType edmEntityType)
throws XMLStreamException, EdmPrimitiveTypeException, DeserializerException {
Entity entity = null;
+ EdmEntityType resolvedType = edmEntityType;
if (entryRefQName.equals(start.getName())) {
entity = entityRef(start);
} else if (Constants.QNAME_ATOM_ELEM_ENTRY.equals(start.getName())) {
@@ -455,7 +483,9 @@ public class ODataXmlDeserializer implements ODataDeserializer {
} else if (Constants.QNAME_ATOM_ELEM_CATEGORY.equals(event.asStartElement().getName())) {
final Attribute term = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATOM_ATTR_TERM));
if (term != null) {
- entity.setType(new EdmTypeInfo.Builder().setTypeExpression(term.getValue()).build().internal());
+ String type = new EdmTypeInfo.Builder().setTypeExpression(term.getValue()).build().internal();
+ entity.setType(type);
+ resolvedType = (EdmEntityType)getDerivedType(edmEntityType, type);
}
} else if (Constants.QNAME_ATOM_ELEM_LINK.equals(event.asStartElement().getName())) {
final Link link = new Link();
@@ -485,7 +515,7 @@ public class ODataXmlDeserializer implements ODataDeserializer {
entity.setMediaETag(mediaETag.getValue());
}
} else if (link.getRel().startsWith(Constants.NS_NAVIGATION_LINK_REL)) {
- inline(reader, event.asStartElement(), link, edmEntityType);
+ inline(reader, event.asStartElement(), link, resolvedType);
if (link.getInlineEntity() == null && link.getInlineEntitySet() == null) {
entity.getNavigationBindings().add(link);
} else {
@@ -525,7 +555,7 @@ public class ODataXmlDeserializer implements ODataDeserializer {
.getAttributeByName(QName.valueOf(Constants.ATTR_TYPE));
if (contenttype == null || ContentType.APPLICATION_XML.toContentTypeString()
.equals(contenttype.getValue())) {
- properties(reader, skipBeforeFirstStartElement(reader), entity, edmEntityType);
+ properties(reader, skipBeforeFirstStartElement(reader), entity, resolvedType);
} else {
entity.setMediaContentType(contenttype.getValue());
final Attribute src = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATOM_ATTR_SRC));
@@ -534,7 +564,7 @@ public class ODataXmlDeserializer implements ODataDeserializer {
}
}
} else if (propertiesQName.equals(event.asStartElement().getName())) {
- properties(reader, event.asStartElement(), entity, edmEntityType);
+ properties(reader, event.asStartElement(), entity, resolvedType);
}
}
@@ -799,4 +829,48 @@ public class ODataXmlDeserializer implements ODataDeserializer {
}
return parameter;
}
+
+ private EdmType getDerivedType(final EdmStructuredType edmType, String odataType)
+ throws DeserializerException {
+ if (odataType != null && !odataType.isEmpty()) {
+
+ if (odataType.equalsIgnoreCase(edmType.getFullQualifiedName().getFullQualifiedNameAsString())) {
+ return edmType;
+ } else if (this.serviceMetadata == null) {
+ throw new DeserializerException(
+ "Failed to resolve Odata type " + odataType + " due to metadata is not available",
+ DeserializerException.MessageKeys.UNKNOWN_CONTENT);
+ }
+
+ EdmStructuredType currentEdmType = null;
+ if(edmType instanceof EdmEntityType) {
+ currentEdmType = serviceMetadata.getEdm()
+ .getEntityType(new FullQualifiedName(odataType));
+ } else {
+ currentEdmType = serviceMetadata.getEdm()
+ .getComplexType(new FullQualifiedName(odataType));
+ }
+ if (!isAssignable(edmType, currentEdmType)) {
+ throw new DeserializerException(
+ "Odata type " + odataType + " not allowed here",
+ DeserializerException.MessageKeys.UNKNOWN_CONTENT);
+ }
+
+ return currentEdmType;
+ }
+ return edmType;
+ }
+
+ private boolean isAssignable(final EdmStructuredType edmStructuredType,
+ final EdmStructuredType edmStructuredTypeToAssign) {
+ if (edmStructuredTypeToAssign == null) {
+ return false;
+ } else if (edmStructuredType.getFullQualifiedName()
+ .equals(edmStructuredTypeToAssign.getFullQualifiedName())) {
+ return true;
+ } else {
+ return isAssignable(edmStructuredType,
+ edmStructuredTypeToAssign.getBaseType());
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/AbstractODataDeserializerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/AbstractODataDeserializerTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/AbstractODataDeserializerTest.java
index c90ad6d..49c4ac9 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/AbstractODataDeserializerTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/AbstractODataDeserializerTest.java
@@ -24,6 +24,7 @@ import java.util.Collections;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.edmx.EdmxReference;
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
@@ -33,7 +34,9 @@ public class AbstractODataDeserializerTest {
protected static final Edm edm = OData.newInstance()
.createServiceMetadata(new EdmTechProvider(), Collections.<EdmxReference> emptyList())
.getEdm();
-
+ protected static final ServiceMetadata metadata = OData.newInstance()
+ .createServiceMetadata(new EdmTechProvider(), Collections.<EdmxReference> emptyList());
+
protected InputStream getFileAsStream(final String filename) throws IOException {
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(filename);
if (in == null) {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerEntityCollectionTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerEntityCollectionTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerEntityCollectionTest.java
index 4b2c6c3..db65c78 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerEntityCollectionTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerEntityCollectionTest.java
@@ -165,14 +165,14 @@ public class ODataDeserializerEntityCollectionTest extends AbstractODataDeserial
private EntityCollection deserialize(final InputStream stream, final String entityTypeName)
throws DeserializerException {
- return OData.newInstance().createDeserializer(ContentType.JSON)
+ return OData.newInstance().createDeserializer(ContentType.JSON, metadata)
.entityCollection(stream, edm.getEntityType(new FullQualifiedName(NAMESPACE, entityTypeName)))
.getEntityCollection();
}
private EntityCollection deserialize(final String input, final String entityTypeName)
throws DeserializerException {
- return OData.newInstance().createDeserializer(ContentType.JSON)
+ return OData.newInstance().createDeserializer(ContentType.JSON, metadata)
.entityCollection(new ByteArrayInputStream(input.getBytes()),
edm.getEntityType(new FullQualifiedName(NAMESPACE, entityTypeName)))
.getEntityCollection();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerActionParametersTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerActionParametersTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerActionParametersTest.java
index 20d4fa2..b1f020e 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerActionParametersTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerActionParametersTest.java
@@ -254,7 +254,7 @@ public class ODataJsonDeserializerActionParametersTest extends AbstractODataDese
private Map<String, Parameter> deserialize(final String input, final String actionName, final String bindingTypeName)
throws DeserializerException {
- return OData.newInstance().createDeserializer(ContentType.JSON)
+ return OData.newInstance().createDeserializer(ContentType.JSON, metadata)
.actionParameters(new ByteArrayInputStream(input.getBytes()),
bindingTypeName == null ?
edm.getUnboundAction(new FullQualifiedName(NAMESPACE, actionName)) :
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java
index 01e61f3..48dc870 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java
@@ -46,10 +46,12 @@ import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.provider.CsdlMapping;
import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmDate;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.deserializer.DeserializerException;
import org.apache.olingo.server.api.deserializer.ODataDeserializer;
import org.apache.olingo.server.core.deserializer.AbstractODataDeserializerTest;
+import org.junit.Assert;
import org.junit.Test;
public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTest {
@@ -218,6 +220,46 @@ public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTe
}
@Test
+ public void extendedComplexProperty() throws Exception {
+
+ final String payload = "{"
+ + "\"@odata.context\":\"$metadata#ESCompComp/$entity\","
+ + "\"@odata.metadataEtag\":\"W/\\\"metadataETag\\\"\","
+ + "\"@odata.etag\":\"W/\\\"32767\\\"\","
+ + "\"PropertyInt16\":32767,"
+ + "\"PropertyComp\":{"
+ + "\"@odata.type\":\"#olingo.odata.test1.CTCompCompExtended\","
+ + "\"PropertyComp\":{"
+ + "\"@odata.type\":\"#olingo.odata.test1.CTTwoPrim\","
+ + "\"PropertyInt16\":32767,"
+ + "\"PropertyString\":\"First Resource - first\""
+ + "},"
+ + "\"PropertyDate\":\"2012-10-03\""
+ + "}}";
+ final Entity result = deserialize(payload, "ETCompComp");
+
+ Assert.assertNotNull(result);
+ Property property = result.getProperty("PropertyComp");
+ Assert.assertEquals("PropertyComp", property.getName());
+ Assert.assertTrue(property.isComplex());
+ final ComplexValue cv = property.asComplex();
+ Assert.assertEquals("olingo.odata.test1.CTCompCompExtended", property.getType());
+ Assert.assertEquals(
+ "2012-10-03",
+ EdmDate.getInstance().valueToString(getCVProperty(cv, "PropertyDate").asPrimitive(), false, 10, 3, 0,
+ false));
+ }
+
+ private Property getCVProperty(ComplexValue cv, String name) {
+ for (Property p : cv.getValue()) {
+ if (p.getName().equals(name)) {
+ return p;
+ }
+ }
+ return null;
+ }
+
+ @Test
public void simpleEntityETCollAllPrim() throws Exception {
final String entityString = "{"
+ "\"PropertyInt16\":1,"
@@ -606,7 +648,7 @@ public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTe
"{\"PropertyDate\":\"2012-12-03\","
+ "\"PropertyDateTimeOffset\":\"2012-12-03T07:16:23Z\"}";
InputStream stream = new ByteArrayInputStream(entityString.getBytes());
- ODataDeserializer deserializer = OData.newInstance().createDeserializer(ContentType.JSON);
+ ODataDeserializer deserializer = OData.newInstance().createDeserializer(ContentType.JSON, metadata);
Entity entity = deserializer.entity(stream, entityType).getEntity();
assertNotNull(entity);
List<Property> properties = entity.getProperties();
@@ -1272,7 +1314,7 @@ public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTe
protected static Entity deserialize(final InputStream stream, final String entityTypeName,
final ContentType contentType) throws DeserializerException {
- return OData.newInstance().createDeserializer(contentType)
+ return OData.newInstance().createDeserializer(contentType, metadata)
.entity(stream, edm.getEntityType(new FullQualifiedName(NAMESPACE, entityTypeName)))
.getEntity();
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/xml/ODataXMLDeserializerActionParametersTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/xml/ODataXMLDeserializerActionParametersTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/xml/ODataXMLDeserializerActionParametersTest.java
index 18162da..539b70f 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/xml/ODataXMLDeserializerActionParametersTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/xml/ODataXMLDeserializerActionParametersTest.java
@@ -234,7 +234,7 @@ public class ODataXMLDeserializerActionParametersTest extends AbstractODataDeser
private Map<String, Parameter> deserialize(final String input, final String actionName, final String bindingTypeName)
throws DeserializerException {
- return OData.newInstance().createDeserializer(ContentType.APPLICATION_XML)
+ return OData.newInstance().createDeserializer(ContentType.APPLICATION_XML, metadata)
.actionParameters(new ByteArrayInputStream(input.getBytes()),
bindingTypeName == null ?
edm.getUnboundAction(new FullQualifiedName(NAMESPACE, actionName)) :
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializerTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializerTest.java
index dcde3f2..416c219 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializerTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializerTest.java
@@ -36,6 +36,7 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.EdmProperty;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmDate;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.deserializer.ODataDeserializer;
import org.apache.olingo.server.core.deserializer.AbstractODataDeserializerTest;
@@ -47,7 +48,7 @@ import org.junit.Test;
public class ODataXmlDeserializerTest extends AbstractODataDeserializerTest {
private static final EdmEntityContainer entityContainer = edm.getEntityContainer();
- private final ODataDeserializer deserializer = new ODataXmlDeserializer();
+ private final ODataDeserializer deserializer = new ODataXmlDeserializer(metadata);
@BeforeClass
public static void setup() {
@@ -535,6 +536,46 @@ public class ODataXmlDeserializerTest extends AbstractODataDeserializerTest {
}
@Test
+ public void extendedComplexProperty() throws Exception {
+ final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCompComp");
+
+ String payload = "<?xml version='1.0' encoding='UTF-8'?>"
+ + "<atom:entry xmlns:atom=\"http://www.w3.org/2005/Atom\" "
+ + "xmlns:metadata=\"http://docs.oasis-open.org/odata/ns/metadata\" "
+ + "xmlns:data=\"http://docs.oasis-open.org/odata/ns/data\" "
+ + "metadata:etag=\"W/"32767"\">"
+ + "<atom:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" "
+ + "term=\"#olingo.odata.test1.ETCompComp\"/>"
+ + "<atom:content type=\"application/xml\">"
+ + "<metadata:properties>"
+ + "<data:PropertyInt16>32767</data:PropertyInt16>"
+ + "<data:PropertyComp metadata:type=\"#olingo.odata.test1.CTCompCompExtended\">"
+ + "<data:PropertyComp metadata:type=\"#olingo.odata.test1.CTTwoPrim\">"
+ + "<data:PropertyInt16>32767</data:PropertyInt16>"
+ + "<data:PropertyString>First Resource - first</data:PropertyString>"
+ + "</data:PropertyComp>"
+ + "<data:PropertyDate>2012-10-03</data:PropertyDate>"
+ + "</data:PropertyComp>"
+ + "</metadata:properties>"
+ + "</atom:content>"
+ + "</atom:entry>";
+
+ Entity result = deserializer.entity(new ByteArrayInputStream(payload.getBytes()),
+ edmEntitySet.getEntityType()).getEntity();
+
+ Assert.assertNotNull(result);
+ Property property = result.getProperty("PropertyComp");
+ Assert.assertEquals("PropertyComp", property.getName());
+ Assert.assertTrue(property.isComplex());
+ final ComplexValue cv = property.asComplex();
+ Assert.assertEquals("olingo.odata.test1.CTCompCompExtended", property.getType());
+ Assert.assertEquals(
+ "2012-10-03",
+ EdmDate.getInstance().valueToString(getCVProperty(cv, "PropertyDate").asPrimitive(), false, 10, 3, 0,
+ false));
+ }
+
+ @Test
public void complexCollectionProperty() throws Exception {
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMixPrimCollComp");
final EdmProperty edmProperty = (EdmProperty) edmEntitySet.getEntityType().getProperty("CollPropertyComp");