You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ch...@apache.org on 2014/12/05 14:42:40 UTC
olingo-odata4 git commit: [OLINGO-507] server support for reading,
changing, and deleting media entities
Repository: olingo-odata4
Updated Branches:
refs/heads/master 297950a8d -> 19a7738a7
[OLINGO-507] server support for reading, changing, and deleting media entities
Change-Id: Ibe16c54cf68e25f0c1e8fb19c212d7c312f5ca85
Signed-off-by: Christian Amend <ch...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/19a7738a
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/19a7738a
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/19a7738a
Branch: refs/heads/master
Commit: 19a7738a718bc52fbe24cb4988cb336923cf06a0
Parents: 297950a
Author: Klaus Straubinger <kl...@sap.com>
Authored: Fri Dec 5 14:28:20 2014 +0100
Committer: Christian Amend <ch...@apache.org>
Committed: Fri Dec 5 14:36:06 2014 +0100
----------------------------------------------------------------------
.../olingo/fit/tecsvc/client/MediaITCase.java | 127 +++++++++++++++++++
.../api/deserializer/DeserializerException.java | 66 ++++++++++
.../deserializer/FixedFormatDeserializer.java | 8 ++
.../server/api/processor/MediaProcessor.java | 80 ++++++++++++
.../apache/olingo/server/core/ODataHandler.java | 67 ++++++++--
.../FixedFormatDeserializerImpl.java | 20 +++
.../server-core-exceptions-i18n.properties | 3 +
.../deserializer/BatchRequestParserTest.java | 25 ++--
.../FixedFormatDeserializerTest.java | 53 ++++++++
.../server/core/deserializer/StringUtil.java | 53 --------
.../serializer/BatchResponseSerializerTest.java | 6 +-
.../olingo/server/tecsvc/data/DataProvider.java | 57 ++++++++-
.../processor/TechnicalEntityProcessor.java | 109 +++++++++++++---
.../olingo/server/core/ODataHandlerTest.java | 44 +++++++
.../json/ODataJsonSerializerTest.java | 10 +-
15 files changed, 626 insertions(+), 102 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/19a7738a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/MediaITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/MediaITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/MediaITCase.java
new file mode 100644
index 0000000..8a1ac8f
--- /dev/null
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/MediaITCase.java
@@ -0,0 +1,127 @@
+/*
+ * 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.assertNotNull;
+import static org.junit.Assert.assertThat;
+
+import java.io.InputStream;
+import java.net.URI;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.olingo.client.api.CommonODataClient;
+import org.apache.olingo.client.api.communication.ODataClientErrorException;
+import org.apache.olingo.client.api.communication.request.cud.ODataDeleteRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataMediaRequest;
+import org.apache.olingo.client.api.communication.request.streamed.ODataMediaEntityUpdateRequest;
+import org.apache.olingo.client.api.communication.response.ODataDeleteResponse;
+import org.apache.olingo.client.api.communication.response.ODataMediaEntityUpdateResponse;
+import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+import org.apache.olingo.client.api.v4.ODataClient;
+import org.apache.olingo.client.core.ODataClientFactory;
+import org.apache.olingo.commons.api.domain.CommonODataEntity;
+import org.apache.olingo.commons.api.domain.CommonODataProperty;
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.format.ODataFormat;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.fit.AbstractBaseTestITCase;
+import org.apache.olingo.fit.tecsvc.TecSvcConst;
+import org.junit.Test;
+
+public final class MediaITCase extends AbstractBaseTestITCase {
+
+ @Test
+ public void read() throws Exception {
+ final CommonODataClient<?> client = getClient();
+ final ODataMediaRequest request = client.getRetrieveRequestFactory().getMediaRequest(
+ client.newURIBuilder(TecSvcConst.BASE_URI)
+ .appendEntitySetSegment("ESMedia").appendKeySegment(1).appendValueSegment().build());
+ assertNotNull(request);
+
+ final ODataRetrieveResponse<InputStream> response = request.execute();
+ assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
+ assertEquals("image/svg+xml", response.getContentType());
+
+ InputStream media = response.getBody();
+ assertNotNull(media);
+ assertThat(IOUtils.toString(media), startsWith("<?xml"));
+ }
+
+ @Test
+ public void delete() {
+ final CommonODataClient<?> client = getClient();
+ final URI uri = client.newURIBuilder(TecSvcConst.BASE_URI)
+ .appendEntitySetSegment("ESMedia").appendKeySegment(4).appendValueSegment().build();
+ final ODataDeleteRequest request = client.getCUDRequestFactory().getDeleteRequest(uri);
+ assertNotNull(request);
+
+ final ODataDeleteResponse response = request.execute();
+ assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode());
+
+ // Check that the media stream is really gone.
+ // This check has to be in the same session in order to access the same data provider.
+ ODataMediaRequest mediaRequest = client.getRetrieveRequestFactory().getMediaRequest(uri);
+ mediaRequest.addCustomHeader(HttpHeader.COOKIE, response.getHeader(HttpHeader.SET_COOKIE).iterator().next());
+ try {
+ mediaRequest.execute();
+ } catch (final ODataClientErrorException e) {
+ assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), e.getStatusLine().getStatusCode());
+ }
+ }
+
+ @Test
+ public void update() throws Exception {
+ final CommonODataClient<?> client = getClient();
+ final URI uri = client.newURIBuilder(TecSvcConst.BASE_URI)
+ .appendEntitySetSegment("ESMedia").appendKeySegment(4).appendValueSegment().build();
+ ODataMediaEntityUpdateRequest<CommonODataEntity> request =
+ client.getCUDRequestFactory().getMediaEntityUpdateRequest(uri,
+ IOUtils.toInputStream("just a test"));
+ request.setContentType(ContentType.TEXT_PLAIN.toContentTypeString());
+ assertNotNull(request);
+
+ final ODataMediaEntityUpdateResponse<CommonODataEntity> response = request.payloadManager().getResponse();
+ assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
+ final CommonODataEntity entity = response.getBody();
+ assertNotNull(entity);
+ final CommonODataProperty property = entity.getProperty("PropertyInt16");
+ assertNotNull(property);
+ assertNotNull(property.getPrimitiveValue());
+ assertEquals(4, property.getPrimitiveValue().toValue());
+
+ // Check that the media stream has changed.
+ // This check has to be in the same session in order to access the same data provider.
+ ODataMediaRequest mediaRequest = client.getRetrieveRequestFactory().getMediaRequest(uri);
+ mediaRequest.addCustomHeader(HttpHeader.COOKIE, response.getHeader(HttpHeader.SET_COOKIE).iterator().next());
+ ODataRetrieveResponse<InputStream> mediaResponse = mediaRequest.execute();
+ assertEquals(HttpStatusCode.OK.getStatusCode(), mediaResponse.getStatusCode());
+ assertEquals(ContentType.TEXT_PLAIN.toContentTypeString(), mediaResponse.getContentType());
+ assertEquals("just a test", IOUtils.toString(mediaResponse.getBody()));
+ }
+
+ @Override
+ protected CommonODataClient<?> getClient() {
+ ODataClient odata = ODataClientFactory.getV4();
+ odata.getConfiguration().setDefaultPubFormat(ODataFormat.JSON);
+ return odata;
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/19a7738a/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/DeserializerException.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/DeserializerException.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/DeserializerException.java
new file mode 100644
index 0000000..2e4e7bc
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/DeserializerException.java
@@ -0,0 +1,66 @@
+/*
+ * 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.api.deserializer;
+
+import org.apache.olingo.server.api.ODataTranslatedException;
+
+/** Exception thrown by deserializers. */
+public class DeserializerException extends ODataTranslatedException {
+
+ private static final long serialVersionUID = 6341270437497060906L;
+
+ /** Keys for exception texts in the resource bundle. */
+ public static enum MessageKeys implements MessageKey {
+ NOT_IMPLEMENTED,
+ IO_EXCEPTION;
+
+ @Override
+ public String getKey() {
+ return name();
+ }
+ }
+
+ /**
+ * Creates deserializer exception.
+ * @param developmentMessage message text as fallback and for debugging purposes
+ * @param messageKey one of the {@link MessageKeys} for the exception text in the resource bundle
+ * @param parameters parameters for the exception text
+ */
+ public DeserializerException(final String developmentMessage,
+ final MessageKey messageKey, final String... parameters) {
+ super(developmentMessage, messageKey, parameters);
+ }
+
+ /**
+ * Creates deserializer exception.
+ * @param developmentMessage message text as fallback and for debugging purposes
+ * @param cause the cause of this exception
+ * @param messageKey one of the {@link MessageKeys} for the exception text in the resource bundle
+ * @param parameters parameters for the exception text
+ */
+ public DeserializerException(final String developmentMessage, final Throwable cause,
+ final MessageKey messageKey, final String... parameters) {
+ super(developmentMessage, cause, messageKey, parameters);
+ }
+
+ @Override
+ protected String getBundleName() {
+ return DEFAULT_SERVER_BUNDLE_NAME;
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/19a7738a/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/FixedFormatDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/FixedFormatDeserializer.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/FixedFormatDeserializer.java
index 1eba75c..0182d6d 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/FixedFormatDeserializer.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/FixedFormatDeserializer.java
@@ -26,6 +26,14 @@ import org.apache.olingo.server.api.deserializer.batch.BatchOptions;
import org.apache.olingo.server.api.deserializer.batch.BatchRequestPart;
public interface FixedFormatDeserializer {
+
+ /**
+ * Reads binary data from an InputStream.
+ * @param content the binary data as input stream
+ * @return the binary data
+ */
+ byte[] binary(InputStream content) throws DeserializerException;
+
public List<BatchRequestPart> parseBatchRequest(InputStream content, String boundary, BatchOptions options)
throws BatchDeserializerException;
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/19a7738a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/MediaProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/MediaProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/MediaProcessor.java
new file mode 100644
index 0000000..fb8ce7d
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/MediaProcessor.java
@@ -0,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.server.api.processor;
+
+import org.apache.olingo.commons.api.format.ContentType;
+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.deserializer.DeserializerException;
+import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.api.uri.UriInfo;
+
+/**
+ * Processor interface for handling Entity Media.
+ */
+public interface MediaProcessor extends Processor {
+
+ /**
+ * Reads entity media data from persistence and puts content and status into the response.
+ * @param request OData request object containing raw HTTP information
+ * @param response OData response object for collecting response data
+ * @param uriInfo information of a parsed OData URI
+ * @param format requested content type after content negotiation
+ * @throws ODataApplicationException if the service implementation encounters a failure
+ * @throws SerializerException if serialization failed
+ */
+ void readMedia(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
+ throws ODataApplicationException, SerializerException;
+
+ /**
+ * Creates entity media data in the persistence and puts content, status, and Location into the response.
+ * @param request OData request object containing raw HTTP information
+ * @param response OData response object for collecting response data
+ * @param uriInfo information of a parsed OData URI
+ * @param format requested content type after content negotiation
+ * @throws ODataApplicationException if the service implementation encounters a failure
+ * @throws DeserializerException if deserialization failed
+ * @throws SerializerException if serialization failed
+ */
+ void createMedia(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
+ throws ODataApplicationException, DeserializerException, SerializerException;
+
+ /**
+ * Updates entity media data in the persistence and puts content and status into the response.
+ * @param request OData request object containing raw HTTP information
+ * @param response OData response object for collecting response data
+ * @param uriInfo information of a parsed OData URI
+ * @param format requested content type after content negotiation
+ * @throws ODataApplicationException if the service implementation encounters a failure
+ * @throws DeserializerException if deserialization failed
+ * @throws SerializerException if serialization failed
+ */
+ void updateMedia(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
+ throws ODataApplicationException, DeserializerException, SerializerException;
+
+ /**
+ * Deletes entity media data from persistence and puts the status into the response.
+ * @param request OData request object containing raw HTTP information
+ * @param response OData response object for collecting response data
+ * @param uriInfo information of a parsed OData URI
+ * @throws ODataApplicationException if the service implementation encounters a failure
+ */
+ void deleteMedia(ODataRequest request, ODataResponse response, UriInfo uriInfo) throws ODataApplicationException;
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/19a7738a/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 63d0dce..51b328b 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
@@ -21,6 +21,7 @@ package org.apache.olingo.server.core;
import java.util.LinkedList;
import java.util.List;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
@@ -36,6 +37,7 @@ 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.batch.exception.BatchException;
+import org.apache.olingo.server.api.deserializer.DeserializerException;
import org.apache.olingo.server.api.processor.BatchProcessor;
import org.apache.olingo.server.api.processor.ComplexCollectionProcessor;
import org.apache.olingo.server.api.processor.ComplexProcessor;
@@ -44,6 +46,7 @@ import org.apache.olingo.server.api.processor.DefaultProcessor;
import org.apache.olingo.server.api.processor.EntityCollectionProcessor;
import org.apache.olingo.server.api.processor.EntityProcessor;
import org.apache.olingo.server.api.processor.ExceptionProcessor;
+import org.apache.olingo.server.api.processor.MediaProcessor;
import org.apache.olingo.server.api.processor.MetadataProcessor;
import org.apache.olingo.server.api.processor.PrimitiveCollectionProcessor;
import org.apache.olingo.server.api.processor.PrimitiveProcessor;
@@ -107,6 +110,9 @@ public class ODataHandler {
} catch (SerializerException e) {
ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e, null);
handleException(request, response, serverError);
+ } catch (DeserializerException e) {
+ ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e, null);
+ handleException(request, response, serverError);
} catch (ODataHandlerException e) {
ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e, null);
handleException(request, response, serverError);
@@ -122,7 +128,7 @@ public class ODataHandler {
private void processInternal(final ODataRequest request, final ODataResponse response)
throws ODataHandlerException, UriParserException, UriValidationException, ContentNegotiatorException,
- ODataApplicationException, SerializerException, BatchException {
+ ODataApplicationException, SerializerException, DeserializerException, BatchException {
validateODataVersion(request, response);
uriInfo = new Parser().parseUri(request.getRawODataPath(), request.getRawQueryPath(), null,
@@ -195,7 +201,8 @@ public class ODataHandler {
}
private void handleResourceDispatching(final ODataRequest request, final ODataResponse response)
- throws ODataHandlerException, ContentNegotiatorException, ODataApplicationException, SerializerException {
+ throws ODataHandlerException, ContentNegotiatorException, ODataApplicationException,
+ SerializerException, DeserializerException {
final HttpMethod method = request.getMethod();
final int lastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 1;
final UriResource lastPathSegment = uriInfo.getUriResourceParts().get(lastPathSegmentIndex);
@@ -210,9 +217,19 @@ public class ODataHandler {
selectProcessor(EntityCollectionProcessor.class)
.readEntityCollection(request, response, uriInfo, requestedContentType);
+ } else if (method.equals(HttpMethod.POST)) {
+ if (isMedia(lastPathSegment)) {
+ final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
+ request, customContentTypeSupport, RepresentationType.ENTITY);
+ selectProcessor(MediaProcessor.class)
+ .createMedia(request, response, uriInfo, requestedContentType);
+ } else {
+ throw new ODataHandlerException("not implemented",
+ ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
+ }
} else {
- throw new ODataHandlerException("not implemented",
- ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
+ throw new ODataHandlerException("HTTP method not allowed.",
+ ODataHandlerException.MessageKeys.HTTP_METHOD_NOT_ALLOWED, method.toString());
}
} else {
if (method.equals(HttpMethod.GET)) {
@@ -221,6 +238,14 @@ public class ODataHandler {
selectProcessor(EntityProcessor.class)
.readEntity(request, response, uriInfo, requestedContentType);
+ } else if (method.equals(HttpMethod.DELETE)) {
+ if (isMedia(lastPathSegment)) {
+ selectProcessor(MediaProcessor.class)
+ .deleteMedia(request, response, uriInfo);
+ } else {
+ throw new ODataHandlerException("not implemented",
+ ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
+ }
} else {
throw new ODataHandlerException("not implemented",
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
@@ -286,9 +311,9 @@ public class ODataHandler {
break;
case value:
- if (method.equals(HttpMethod.GET)) {
- final UriResource resource = uriInfo.getUriResourceParts().get(lastPathSegmentIndex - 1);
- if (resource instanceof UriResourceProperty) {
+ final UriResource resource = uriInfo.getUriResourceParts().get(lastPathSegmentIndex - 1);
+ if (resource instanceof UriResourceProperty) {
+ if (method.equals(HttpMethod.GET)) {
final RepresentationType representationType =
(EdmPrimitiveType) ((UriResourceProperty) resource).getType() ==
EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary) ?
@@ -299,12 +324,27 @@ public class ODataHandler {
selectProcessor(PrimitiveProcessor.class)
.readPrimitiveAsValue(request, response, uriInfo, requestedContentType);
} else {
- throw new ODataHandlerException("Media Entity is not implemented.",
+ throw new ODataHandlerException("not implemented",
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
}
} else {
- throw new ODataHandlerException("not implemented",
- ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
+ if (method.equals(HttpMethod.GET)) {
+ final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
+ request, customContentTypeSupport, RepresentationType.MEDIA);
+ selectProcessor(MediaProcessor.class)
+ .readMedia(request, response, uriInfo, requestedContentType);
+ } else if (method.equals(HttpMethod.PUT)) {
+ final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
+ request, customContentTypeSupport, RepresentationType.ENTITY);
+ selectProcessor(MediaProcessor.class)
+ .updateMedia(request, response, uriInfo, requestedContentType);
+ } else if (method.equals(HttpMethod.DELETE)) {
+ selectProcessor(MediaProcessor.class)
+ .deleteMedia(request, response, uriInfo);
+ } else {
+ throw new ODataHandlerException("not implemented",
+ ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
+ }
}
break;
@@ -327,6 +367,13 @@ public class ODataHandler {
}
}
+ private boolean isMedia(final UriResource pathSegment) {
+ return pathSegment instanceof UriResourceEntitySet
+ && ((UriResourceEntitySet) pathSegment).getEntityType().hasStream()
+ || pathSegment instanceof UriResourceNavigation
+ && ((EdmEntityType) ((UriResourceNavigation) pathSegment).getType()).hasStream();
+ }
+
private <T extends Processor> T selectProcessor(final Class<T> cls) throws ODataHandlerException {
for (final Processor processor : processors) {
if (cls.isAssignableFrom(processor.getClass())) {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/19a7738a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/FixedFormatDeserializerImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/FixedFormatDeserializerImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/FixedFormatDeserializerImpl.java
index 65feae7..a34aa95 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/FixedFormatDeserializerImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/FixedFormatDeserializerImpl.java
@@ -18,10 +18,13 @@
*/
package org.apache.olingo.server.core.deserializer;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.apache.olingo.server.api.batch.exception.BatchDeserializerException;
+import org.apache.olingo.server.api.deserializer.DeserializerException;
import org.apache.olingo.server.api.deserializer.FixedFormatDeserializer;
import org.apache.olingo.server.api.deserializer.batch.BatchOptions;
import org.apache.olingo.server.api.deserializer.batch.BatchRequestPart;
@@ -29,6 +32,23 @@ import org.apache.olingo.server.core.deserializer.batch.BatchParser;
public class FixedFormatDeserializerImpl implements FixedFormatDeserializer {
+ @Override
+ public byte[] binary(InputStream content) throws DeserializerException {
+ ByteArrayOutputStream result = new ByteArrayOutputStream();
+ byte[] buffer = new byte[128];
+ int count = -1;
+ try {
+ while ((count = content.read(buffer)) > -1) {
+ result.write(buffer, 0, count);
+ }
+ result.flush();
+ } catch (final IOException e) {
+ throw new DeserializerException("An I/O exception occurred.", e,
+ DeserializerException.MessageKeys.IO_EXCEPTION);
+ }
+ return result.toByteArray();
+ }
+
// TODO: Deserializer
@Override
public List<BatchRequestPart> parseBatchRequest(InputStream content, String boundary, BatchOptions options)
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/19a7738a/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 ebba201..e28c3e5 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
@@ -96,6 +96,9 @@ SerializerException.MISSING_PROPERTY=The non-nullable property '%1$s' is missing
SerializerException.WRONG_PROPERTY_VALUE=The value '%2$s' is not valid for property '%1$s'.
SerializerException.WRONG_PRIMITIVE_VALUE=The value '%2$s' is not valid for the primitive type '%1$s' and the given facets.
+DeserializerException.NOT_IMPLEMENTED=The requested deserialization method has not been implemented yet.
+DeserializerException.IO_EXCEPTION=An I/O exception occurred.
+
BatchDeserializerException.INVALID_BOUNDARY=Invalid boundary at line '%1$s'.
BatchDeserializerException.INVALID_CHANGESET_METHOD=Invalid method: a ChangeSet cannot contain retrieve requests at line '%1$s'.
BatchDeserializerException.INVALID_CONTENT=Retrieve requests must not contain any body content '%1$s'.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/19a7738a/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/BatchRequestParserTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/BatchRequestParserTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/BatchRequestParserTest.java
index 7a63874..219167d 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/BatchRequestParserTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/BatchRequestParserTest.java
@@ -28,6 +28,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.List;
+import org.apache.commons.io.IOUtils;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.server.api.ODataRequest;
@@ -101,7 +102,7 @@ public class BatchRequestParserTest {
@Test
public void testImageInContent() throws Exception {
final InputStream contentInputStream = readFile("/batchWithContent.batch");
- final String content = StringUtil.toString(contentInputStream);
+ final String content = IOUtils.toString(contentInputStream);
final String batch = ""
+ "--batch_8194-cf13-1f56" + CRLF
+ MIME_HEADERS
@@ -148,7 +149,7 @@ public class BatchRequestParserTest {
assertEquals("application/octet-stream", request.getHeader(HttpHeader.CONTENT_TYPE));
final InputStream body = request.getBody();
- assertEquals(content, StringUtil.toString(body));
+ assertEquals(content, IOUtils.toString(body));
}
}
}
@@ -199,7 +200,7 @@ public class BatchRequestParserTest {
final BatchParser parser = new BatchParser();
final BatchOptions batchOptions = BatchOptions.with().isStrict(true).rawBaseUri(SERVICE_ROOT).build();
final List<BatchRequestPart> batchRequestParts =
- parser.parseBatchRequest(StringUtil.toInputStream(batch), boundary, batchOptions);
+ parser.parseBatchRequest(IOUtils.toInputStream(batch), boundary, batchOptions);
assertNotNull(batchRequestParts);
assertFalse(batchRequestParts.isEmpty());
@@ -754,7 +755,7 @@ public class BatchRequestParserTest {
assertEquals(1, multipart.getRequests().size());
final ODataRequest request = multipart.getRequests().get(0);
- assertEquals("{\"EmployeeName\":\"Peter Fall\"}", StringUtil.toString(request.getBody()));
+ assertEquals("{\"EmployeeName\":\"Peter Fall\"}", IOUtils.toString(request.getBody()));
}
}
}
@@ -786,7 +787,7 @@ public class BatchRequestParserTest {
assertEquals(1, multipart.getRequests().size());
final ODataRequest request = multipart.getRequests().get(0);
- assertEquals("{\"Employee", StringUtil.toString(request.getBody()));
+ assertEquals("{\"Employee", IOUtils.toString(request.getBody()));
}
}
}
@@ -841,7 +842,7 @@ public class BatchRequestParserTest {
final ODataRequest changeRequest = part.getRequests().get(0);
assertEquals("{\"EmployeeName\":\"Frederic Fall MODIFIED\"}",
- StringUtil.toString(changeRequest.getBody()));
+ IOUtils.toString(changeRequest.getBody()));
assertEquals("application/json;odata=verbose", changeRequest.getHeader(HttpHeader.CONTENT_TYPE));
assertEquals(HttpMethod.PUT, changeRequest.getMethod());
}
@@ -1016,9 +1017,9 @@ public class BatchRequestParserTest {
assertEquals(2, changeSetPart.getRequests().size());
assertEquals("/9j/4AAQSkZJRgABAQEBLAEsAAD/4RM0RXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEAAAEaAAUAAAABAAAAYgEbAAUAAAA"
+ CRLF,
- StringUtil.toString(changeSetPart.getRequests().get(0).getBody()));
+ IOUtils.toString(changeSetPart.getRequests().get(0).getBody()));
assertEquals("{\"EmployeeName\":\"Peter Fall\"}",
- StringUtil.toString(changeSetPart.getRequests().get(1).getBody()));
+ IOUtils.toString(changeSetPart.getRequests().get(1).getBody()));
}
@Test
@@ -1126,9 +1127,9 @@ public class BatchRequestParserTest {
assertEquals(2, changeSetPart.getRequests().size());
assertEquals("/9j/4AAQSkZJRgABAQEBLAEsAAD/4RM0RXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEAAAEaAAUAAAABAAAAYgEbAAUAAAA"
+ CRLF,
- StringUtil.toString(changeSetPart.getRequests().get(0).getBody()));
+ IOUtils.toString(changeSetPart.getRequests().get(0).getBody()));
assertEquals("{\"EmployeeName\":\"Peter Fall\"}",
- StringUtil.toString(changeSetPart.getRequests().get(1).getBody()));
+ IOUtils.toString(changeSetPart.getRequests().get(1).getBody()));
}
@Test
@@ -1247,7 +1248,7 @@ public class BatchRequestParserTest {
}
private List<BatchRequestPart> parse(final String batch, final boolean isStrict) throws Exception {
- return parse(StringUtil.toInputStream(batch), isStrict);
+ return parse(IOUtils.toInputStream(batch), isStrict);
}
private void parseInvalidBatchBody(final String batch, final MessageKeys key, final boolean isStrict)
@@ -1255,7 +1256,7 @@ public class BatchRequestParserTest {
final BatchParser parser = new BatchParser();
final BatchOptions options = BatchOptions.with().isStrict(isStrict).rawBaseUri(SERVICE_ROOT).build();
try {
- parser.parseBatchRequest(StringUtil.toInputStream(batch), BOUNDARY, options);
+ parser.parseBatchRequest(IOUtils.toInputStream(batch), BOUNDARY, options);
fail("No exception thrown. Expect: " + key.toString());
} catch (BatchDeserializerException e) {
assertMessageKey(e, key);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/19a7738a/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/FixedFormatDeserializerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/FixedFormatDeserializerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/FixedFormatDeserializerTest.java
new file mode 100644
index 0000000..27f6a5d
--- /dev/null
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/FixedFormatDeserializerTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.deserializer;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.deserializer.FixedFormatDeserializer;
+import org.apache.olingo.server.api.serializer.SerializerException;
+import org.junit.Test;
+
+public class FixedFormatDeserializerTest {
+
+ private final FixedFormatDeserializer deserializer;
+
+ public FixedFormatDeserializerTest() throws SerializerException {
+ deserializer = OData.newInstance().createFixedFormatDeserializer();
+ }
+
+ @Test
+ public void binary() throws Exception {
+ assertArrayEquals(new byte [] { 0x41, 0x42, 0x43 },
+ deserializer.binary(IOUtils.toInputStream("ABC")));
+ }
+
+ @Test
+ public void binaryLong() throws Exception {
+ assertEquals(4 * 3 * 26,
+ deserializer.binary(IOUtils.toInputStream(
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ + "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ + "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ + "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ")).length);
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/19a7738a/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/StringUtil.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/StringUtil.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/StringUtil.java
deleted file mode 100644
index f9ec664..0000000
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/StringUtil.java
+++ /dev/null
@@ -1,53 +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.server.core.deserializer;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.UnsupportedEncodingException;
-
-import org.apache.olingo.commons.api.ODataRuntimeException;
-import org.apache.olingo.server.core.deserializer.batch.BufferedReaderIncludingLineEndings;
-
-public class StringUtil {
-
-
- public static String toString(final InputStream in) throws Exception {
- final StringBuilder builder = new StringBuilder();
- final BufferedReaderIncludingLineEndings reader = new BufferedReaderIncludingLineEndings(new InputStreamReader(in));
- String currentLine;
-
- while((currentLine = reader.readLine()) != null) {
- builder.append(currentLine);
- }
-
- reader.close();
-
- return builder.toString();
- }
-
- public static InputStream toInputStream(final String string) {
- try {
- return new ByteArrayInputStream(string.getBytes("UTF-8"));
- } catch (UnsupportedEncodingException e) {
- throw new ODataRuntimeException("Charset UTF-8 not found");
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/19a7738a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java
index d889cac..ce88c92 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java
@@ -28,11 +28,11 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
+import org.apache.commons.io.IOUtils;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.deserializer.batch.ODataResponsePart;
-import org.apache.olingo.server.core.deserializer.StringUtil;
import org.apache.olingo.server.core.deserializer.batch.BatchParserCommon;
import org.apache.olingo.server.core.deserializer.batch.BufferedReaderIncludingLineEndings;
import org.apache.olingo.server.core.serializer.BatchResponseSerializer;
@@ -48,7 +48,7 @@ public class BatchResponseSerializerTest {
ODataResponse response = new ODataResponse();
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, "application/json");
- response.setContent(StringUtil.toInputStream("Walter Winter" + CRLF));
+ response.setContent(IOUtils.toInputStream("Walter Winter" + CRLF));
List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
responses.add(response);
@@ -104,7 +104,7 @@ public class BatchResponseSerializerTest {
ODataResponse response = new ODataResponse();
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, "application/json");
- response.setContent(StringUtil.toInputStream("Walter Winter"));
+ response.setContent(IOUtils.toInputStream("Walter Winter"));
List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
responses.add(response);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/19a7738a/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 6010e95..34e36a2 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
@@ -18,11 +18,13 @@
*/
package org.apache.olingo.server.tecsvc.data;
+import java.nio.charset.Charset;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -52,6 +54,7 @@ import org.apache.olingo.server.api.uri.UriParameter;
public class DataProvider {
private static final UUID GUID = UUID.fromString("01234567-89ab-cdef-0123-456789abcdef");
+ private static final String MEDIA_PROPERTY_NAME = "$value";
private Map<String, EntitySet> data;
@@ -107,6 +110,43 @@ public class DataProvider {
}
}
+ public void delete(final EdmEntitySet edmEntitySet, final Entity entity) throws DataProviderException {
+ deleteLinksTo(entity);
+ data.get(edmEntitySet.getName()).getEntities().remove(entity);
+ }
+
+ public void deleteLinksTo(final Entity to) throws DataProviderException {
+ for (final String entitySet : data.keySet()) {
+ for (final Entity entity : data.get(entitySet).getEntities()) {
+ for (Iterator<Link> linkIterator = entity.getNavigationLinks().iterator(); linkIterator.hasNext();) {
+ final Link link = linkIterator.next();
+ if (to.equals(link.getInlineEntity())) {
+ linkIterator.remove();
+ } else if (link.getInlineEntitySet() != null) {
+ for (Iterator<Entity> iterator = link.getInlineEntitySet().getEntities().iterator(); iterator.hasNext();) {
+ if (to.equals(iterator.next())) {
+ iterator.remove();
+ }
+ }
+ if (link.getInlineEntitySet().getEntities().isEmpty()) {
+ linkIterator.remove();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public byte[] readMedia(final Entity entity) {
+ return (byte[]) entity.getProperty(MEDIA_PROPERTY_NAME).asPrimitive();
+ }
+
+ public void setMedia(Entity entity, byte[] media, String type) {
+ entity.getProperties().remove(entity.getProperty(MEDIA_PROPERTY_NAME));
+ entity.addProperty(createPrimitive(MEDIA_PROPERTY_NAME, media));
+ entity.setMediaContentType(type);
+ }
+
public static class DataProviderException extends ODataApplicationException {
private static final long serialVersionUID = 5098059649321796156L;
@@ -455,27 +495,36 @@ public class DataProvider {
Entity entity = new EntityImpl();
entity.addProperty(createPrimitive("PropertyInt16", 1));
- entity.setMediaContentType("image/png");
+ setMedia(entity, createImage("darkturquoise"), "image/svg+xml");
entitySet.getEntities().add(entity);
entity = new EntityImpl();
entity.addProperty(createPrimitive("PropertyInt16", 2));
- entity.setMediaContentType("image/bmp");
+ setMedia(entity, createImage("royalblue"), "image/svg+xml");
entitySet.getEntities().add(entity);
entity = new EntityImpl();
entity.addProperty(createPrimitive("PropertyInt16", 3));
- entity.setMediaContentType("image/jpeg");
+ setMedia(entity, createImage("crimson"), "image/svg+xml");
entitySet.getEntities().add(entity);
entity = new EntityImpl();
entity.addProperty(createPrimitive("PropertyInt16", 4));
- entity.setMediaContentType("foo");
+ setMedia(entity, createImage("black"), "image/svg+xml");
entitySet.getEntities().add(entity);
return entitySet;
}
+ private static byte[] createImage(final String color) {
+ return ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ + "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 100 100\">\n"
+ + " <g stroke=\"darkmagenta\" stroke-width=\"16\" fill=\"" + color + "\">\n"
+ + " <circle cx=\"50\" cy=\"50\" r=\"42\"/>\n"
+ + " </g>\n"
+ + "</svg>\n").getBytes(Charset.forName("UTF-8"));
+ }
+
private void linkESTwoPrim() {
EntitySet entitySet = data.get("ESTwoPrim");
final List<Entity> targetEntities = data.get("ESAllPrim").getEntities();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/19a7738a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
index 971c50a..700e3cf 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
@@ -33,9 +33,11 @@ import org.apache.olingo.commons.api.http.HttpStatusCode;
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.deserializer.DeserializerException;
import org.apache.olingo.server.api.processor.CountEntityCollectionProcessor;
import org.apache.olingo.server.api.processor.EntityCollectionProcessor;
import org.apache.olingo.server.api.processor.EntityProcessor;
+import org.apache.olingo.server.api.processor.MediaProcessor;
import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
@@ -43,6 +45,7 @@ import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
+import org.apache.olingo.server.api.uri.UriResourceKind;
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
import org.apache.olingo.server.tecsvc.data.DataProvider;
@@ -51,7 +54,7 @@ import org.apache.olingo.server.tecsvc.data.DataProvider;
* Technical Processor for entity-related functionality.
*/
public class TechnicalEntityProcessor extends TechnicalProcessor
- implements EntityCollectionProcessor, CountEntityCollectionProcessor, EntityProcessor {
+ implements EntityCollectionProcessor, CountEntityCollectionProcessor, EntityProcessor, MediaProcessor {
public TechnicalEntityProcessor(final DataProvider dataProvider) {
super(dataProvider);
@@ -61,10 +64,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
public void readEntityCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType requestedContentType) throws ODataApplicationException, SerializerException {
validateOptions(uriInfo.asUriInfoResource());
- if (uriInfo.asUriInfoResource().getUriResourceParts().size() > 1) {
- throw new ODataApplicationException("Invalid resource type.",
- HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
- }
+ blockNavigation(uriInfo);
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
final EntitySet entitySet = readEntitySetInternal(edmEntitySet,
@@ -92,14 +92,12 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
public void countEntityCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType requestedContentType) throws ODataApplicationException, SerializerException {
validateOptions(uriInfo.asUriInfoResource());
+ blockNavigation(uriInfo);
+
final List<UriResource> resourceParts = uriInfo.asUriInfoResource().getUriResourceParts();
- final int pos = resourceParts.size() - 2;
- if (pos > 0) {
- throw new ODataApplicationException("Invalid resource type.",
- HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
- }
final EntitySet entitySet =
- readEntitySetInternal(((UriResourceEntitySet) resourceParts.get(pos)).getEntitySet(), true);
+ readEntitySetInternal(((UriResourceEntitySet) resourceParts.get(resourceParts.size() - 2)).getEntitySet(),
+ true);
if (entitySet == null) {
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
} else {
@@ -113,10 +111,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
public void readEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType requestedContentType) throws ODataApplicationException, SerializerException {
validateOptions(uriInfo.asUriInfoResource());
- if (uriInfo.asUriInfoResource().getUriResourceParts().size() > 1) {
- throw new ODataApplicationException("Invalid resource type.",
- HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
- }
+ blockNavigation(uriInfo);
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) uriInfo.getUriResourceParts().get(0);
@@ -140,6 +135,90 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
}
}
+ @Override
+ public void readMedia(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
+ final ContentType requestedContentType) throws ODataApplicationException, SerializerException {
+ blockNavigation(uriInfo);
+ final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) uriInfo.getUriResourceParts().get(0);
+ final Entity entity = dataProvider.read(resourceEntitySet.getEntitySet(), resourceEntitySet.getKeyPredicates());
+ if (entity == null) {
+ throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
+ } else {
+ response.setContent(odata.createFixedFormatSerializer()
+ .binary(dataProvider.readMedia(entity)));
+ response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+ response.setHeader(HttpHeader.CONTENT_TYPE, entity.getMediaContentType());
+ }
+ }
+
+ @Override
+ public void createMedia(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
+ final ContentType requestedContentType)
+ throws ODataApplicationException, DeserializerException, SerializerException {
+ blockNavigation(uriInfo);
+ final String contentType = request.getHeader(HttpHeader.CONTENT_TYPE);
+ if (contentType == null) {
+ throw new ODataApplicationException("The Content-Type HTTP header is missing.",
+ HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
+ }
+ throw new ODataApplicationException("Not yet supported.",
+ HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+ }
+
+ @Override
+ public void updateMedia(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
+ final ContentType requestedContentType)
+ throws ODataApplicationException, DeserializerException, SerializerException {
+ blockNavigation(uriInfo);
+ final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) uriInfo.getUriResourceParts().get(0);
+ final EdmEntitySet edmEntitySet = resourceEntitySet.getEntitySet();
+ final Entity entity = dataProvider.read(edmEntitySet, resourceEntitySet.getKeyPredicates());
+ if (entity == null) {
+ throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
+ }
+ final String contentType = request.getHeader(HttpHeader.CONTENT_TYPE);
+ if (contentType == null) {
+ throw new ODataApplicationException("The Content-Type HTTP header is missing.",
+ HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
+ }
+ dataProvider.setMedia(entity, odata.createFixedFormatDeserializer().binary(request.getBody()), contentType);
+
+ final ODataFormat format = ODataFormat.fromContentType(requestedContentType);
+ ODataSerializer serializer = odata.createSerializer(format);
+ response.setContent(serializer.entity(edmEntitySet.getEntityType(), entity,
+ EntitySerializerOptions.with()
+ .contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
+ getContextUrl(serializer, edmEntitySet, true, null, null))
+ .build()));
+ response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+ response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
+ }
+
+ @Override
+ public void deleteMedia(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
+ throws ODataApplicationException {
+ blockNavigation(uriInfo);
+ final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) uriInfo.getUriResourceParts().get(0);
+ final Entity entity = dataProvider.read(resourceEntitySet.getEntitySet(), resourceEntitySet.getKeyPredicates());
+ if (entity == null) {
+ throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
+ } else {
+ dataProvider.delete(resourceEntitySet.getEntitySet(), entity);
+ response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
+ }
+ }
+
+ private void blockNavigation(final UriInfo uriInfo) throws ODataApplicationException {
+ final List<UriResource> parts = uriInfo.asUriInfoResource().getUriResourceParts();
+ if (parts.size() > 2
+ || parts.size() == 2
+ && parts.get(1).getKind() != UriResourceKind.count
+ && parts.get(1).getKind() != UriResourceKind.value) {
+ throw new ODataApplicationException("Invalid resource type.",
+ HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+ }
+ }
+
private EntitySet readEntitySetInternal(final EdmEntitySet edmEntitySet, final boolean withCount)
throws DataProvider.DataProviderException {
EntitySet entitySet = dataProvider.readAll(edmEntitySet);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/19a7738a/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerTest.java
index b4e04fb..cad616d 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerTest.java
@@ -53,6 +53,7 @@ import org.apache.olingo.server.api.processor.ComplexProcessor;
import org.apache.olingo.server.api.processor.CountEntityCollectionProcessor;
import org.apache.olingo.server.api.processor.EntityCollectionProcessor;
import org.apache.olingo.server.api.processor.EntityProcessor;
+import org.apache.olingo.server.api.processor.MediaProcessor;
import org.apache.olingo.server.api.processor.MetadataProcessor;
import org.apache.olingo.server.api.processor.PrimitiveCollectionProcessor;
import org.apache.olingo.server.api.processor.PrimitiveProcessor;
@@ -257,6 +258,49 @@ public class ODataHandlerTest {
}
@Test
+ public void dispatchMedia() throws Exception {
+ final MediaProcessor processor = mock(MediaProcessor.class);
+ dispatch(HttpMethod.GET, "ESMedia(1)/$value", processor);
+
+ verify(processor).readMedia(
+ any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
+ }
+
+ @Test
+ public void dispatchMediaCreate() throws Exception {
+ final MediaProcessor processor = mock(MediaProcessor.class);
+ dispatch(HttpMethod.POST, "ESMedia", processor);
+
+ verify(processor).createMedia(
+ any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
+ }
+
+ @Test
+ public void dispatchMediaPut() throws Exception {
+ final MediaProcessor processor = mock(MediaProcessor.class);
+ dispatch(HttpMethod.PUT, "ESMedia(1)/$value", processor);
+
+ verify(processor).updateMedia(
+ any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
+ }
+
+ @Test
+ public void dispatchMediaDelete() throws Exception {
+ final MediaProcessor processor = mock(MediaProcessor.class);
+ dispatch(HttpMethod.DELETE, "ESMedia(1)/$value", processor);
+
+ verify(processor).deleteMedia(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));
+ }
+
+ @Test
+ public void dispatchMediaDeleteIndirect() throws Exception {
+ final MediaProcessor processor = mock(MediaProcessor.class);
+ dispatch(HttpMethod.DELETE, "ESMedia(1)", processor);
+
+ verify(processor).deleteMedia(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));
+ }
+
+ @Test
public void dispatchPrimitiveProperty() throws Exception {
final PrimitiveProcessor processor = mock(PrimitiveProcessor.class);
dispatch(HttpMethod.GET, "ESAllPrim(0)/PropertyInt16", processor);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/19a7738a/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 f0801d8..7ca442a 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
@@ -325,7 +325,7 @@ public class ODataJsonSerializerTest {
.contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
.build()));
final String expectedResult = "{\"@odata.context\":\"$metadata#ESMedia/$entity\","
- + "\"@odata.mediaEtag\":\"theMediaETag\",\"@odata.mediaContentType\":\"image/png\","
+ + "\"@odata.mediaEtag\":\"theMediaETag\",\"@odata.mediaContentType\":\"image/svg+xml\","
+ "\"PropertyInt16\":1}";
Assert.assertEquals(expectedResult, resultString);
}
@@ -338,10 +338,10 @@ public class ODataJsonSerializerTest {
EntityCollectionSerializerOptions.with()
.contextURL(ContextURL.with().entitySet(edmEntitySet).build()).build()));
final String expectedResult = "{\"@odata.context\":\"$metadata#ESMedia\",\"value\":["
- + "{\"@odata.mediaContentType\":\"image/png\",\"PropertyInt16\":1},"
- + "{\"@odata.mediaContentType\":\"image/bmp\",\"PropertyInt16\":2},"
- + "{\"@odata.mediaContentType\":\"image/jpeg\",\"PropertyInt16\":3},"
- + "{\"@odata.mediaContentType\":\"foo\",\"PropertyInt16\":4}]}";
+ + "{\"@odata.mediaContentType\":\"image/svg+xml\",\"PropertyInt16\":1},"
+ + "{\"@odata.mediaContentType\":\"image/svg+xml\",\"PropertyInt16\":2},"
+ + "{\"@odata.mediaContentType\":\"image/svg+xml\",\"PropertyInt16\":3},"
+ + "{\"@odata.mediaContentType\":\"image/svg+xml\",\"PropertyInt16\":4}]}";
Assert.assertEquals(expectedResult, resultString);
}