blob: 2565555d8cb21a87837d84a33d91487993976928 [file] [log] [blame]
/*
* 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.tecsvc.processor;
import java.io.InputStream;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.data.ContextURL.Builder;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.Link;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.edm.EdmComplexType;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.edm.EdmReturnType;
import org.apache.olingo.commons.api.edm.EdmStructuredType;
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.HttpMethod;
import org.apache.olingo.commons.api.http.HttpStatusCode;
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.ServiceMetadata;
import org.apache.olingo.server.api.deserializer.FixedFormatDeserializer;
import org.apache.olingo.server.api.prefer.Preferences.Return;
import org.apache.olingo.server.api.prefer.PreferencesApplied;
import org.apache.olingo.server.api.processor.ComplexCollectionProcessor;
import org.apache.olingo.server.api.processor.ComplexProcessor;
import org.apache.olingo.server.api.processor.CountComplexCollectionProcessor;
import org.apache.olingo.server.api.processor.CountPrimitiveCollectionProcessor;
import org.apache.olingo.server.api.processor.PrimitiveCollectionProcessor;
import org.apache.olingo.server.api.processor.PrimitiveProcessor;
import org.apache.olingo.server.api.processor.PrimitiveValueProcessor;
import org.apache.olingo.server.api.serializer.ComplexSerializerOptions;
import org.apache.olingo.server.api.serializer.FixedFormatSerializer;
import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
import org.apache.olingo.server.api.serializer.PrimitiveValueSerializerOptions;
import org.apache.olingo.server.api.serializer.RepresentationType;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.serializer.SerializerResult;
import org.apache.olingo.server.api.uri.UriHelper;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.UriInfoResource;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourceComplexProperty;
import org.apache.olingo.server.api.uri.UriResourceFunction;
import org.apache.olingo.server.api.uri.UriResourceKind;
import org.apache.olingo.server.api.uri.UriResourceProperty;
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;
import org.apache.olingo.server.tecsvc.data.DataProvider.DataProviderException;
/**
* Technical Processor which provides functionality related to primitive and complex types and collections thereof.
*/
public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
implements PrimitiveProcessor, PrimitiveValueProcessor,
PrimitiveCollectionProcessor, CountPrimitiveCollectionProcessor,
ComplexProcessor, ComplexCollectionProcessor, CountComplexCollectionProcessor {
private static final String EDMSTREAM = "Edm.Stream";
public TechnicalPrimitiveComplexProcessor(final DataProvider dataProvider,
final ServiceMetadata serviceMetadata) {
super(dataProvider, serviceMetadata);
}
@Override
public void readPrimitive(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType contentType) throws ODataApplicationException, ODataLibraryException {
readProperty(request, response, uriInfo, contentType, RepresentationType.PRIMITIVE);
}
@Override
public void readPrimitiveValue(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType contentType) throws ODataApplicationException, ODataLibraryException {
readProperty(request, response, uriInfo, contentType, RepresentationType.VALUE);
}
@Override
public void updatePrimitive(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType requestFormat, final ContentType responseFormat)
throws ODataApplicationException, ODataLibraryException {
updateProperty(request, response, uriInfo, requestFormat, responseFormat, RepresentationType.PRIMITIVE);
}
@Override
public void updatePrimitiveValue(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType requestFormat, final ContentType responseFormat)
throws ODataApplicationException, ODataLibraryException {
updateProperty(request, response, uriInfo, requestFormat, responseFormat, RepresentationType.VALUE);
}
@Override
public void deletePrimitive(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
throws ODataApplicationException, ODataLibraryException {
deleteProperty(request, response, uriInfo, false);
}
@Override
public void deletePrimitiveValue(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
throws ODataApplicationException, ODataLibraryException {
deleteProperty(request, response, uriInfo, true);
}
@Override
public void readPrimitiveCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType contentType) throws ODataApplicationException, ODataLibraryException {
readProperty(request, response, uriInfo, contentType, RepresentationType.COLLECTION_PRIMITIVE);
}
@Override
public void countPrimitiveCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
throws ODataApplicationException, ODataLibraryException {
readProperty(request, response, uriInfo, ContentType.TEXT_PLAIN, RepresentationType.COUNT);
}
@Override
public void updatePrimitiveCollection(final ODataRequest request, ODataResponse response,
final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat)
throws ODataApplicationException, ODataLibraryException {
updateProperty(request, response, uriInfo, requestFormat, responseFormat, RepresentationType.COLLECTION_PRIMITIVE);
}
@Override
public void deletePrimitiveCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
throws ODataApplicationException, ODataLibraryException {
deleteProperty(request, response, uriInfo, false);
}
@Override
public void readComplex(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType contentType) throws ODataApplicationException, ODataLibraryException {
readProperty(request, response, uriInfo, contentType, RepresentationType.COMPLEX);
}
@Override
public void updateComplex(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType requestFormat, final ContentType responseFormat)
throws ODataApplicationException, ODataLibraryException {
updateProperty(request, response, uriInfo, requestFormat, responseFormat, RepresentationType.COMPLEX);
}
@Override
public void deleteComplex(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
throws ODataApplicationException, ODataLibraryException {
deleteProperty(request, response, uriInfo, false);
}
@Override
public void readComplexCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType contentType) throws ODataApplicationException, ODataLibraryException {
readProperty(request, response, uriInfo, contentType, RepresentationType.COLLECTION_COMPLEX);
}
@Override
public void countComplexCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
throws ODataApplicationException, ODataLibraryException {
readProperty(request, response, uriInfo, ContentType.TEXT_PLAIN, RepresentationType.COUNT);
}
@Override
public void updateComplexCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType requestFormat, final ContentType responseFormat)
throws ODataApplicationException, ODataLibraryException {
updateProperty(request, response, uriInfo, requestFormat, responseFormat, RepresentationType.COLLECTION_COMPLEX);
}
@Override
public void deleteComplexCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
throws ODataApplicationException, ODataLibraryException {
deleteProperty(request, response, uriInfo, false);
}
private void readProperty(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType contentType, final RepresentationType representationType)
throws ODataApplicationException, ODataLibraryException {
final UriInfoResource resource = uriInfo.asUriInfoResource();
validateOptions(resource);
validatePath(resource);
final EdmEntitySet edmEntitySet = getEdmEntitySet(resource);
final List<UriResource> resourceParts = resource.getUriResourceParts();
final int trailing =
representationType == RepresentationType.COUNT || representationType == RepresentationType.VALUE ? 1 : 0;
final List<String> path = getPropertyPath(resourceParts, trailing);
final Entity entity = readEntity(uriInfo);
if (entity != null && entity.getETag() != null) {
if (odata.createETagHelper().checkReadPreconditions(entity.getETag(),
request.getHeaders(HttpHeader.IF_MATCH),
request.getHeaders(HttpHeader.IF_NONE_MATCH))) {
response.setStatusCode(HttpStatusCode.NOT_MODIFIED.getStatusCode());
response.setHeader(HttpHeader.ETAG, entity.getETag());
return;
}
}
final Property property = entity == null ?
getPropertyData(
dataProvider.readFunctionPrimitiveComplex(((UriResourceFunction) resourceParts.get(0)).getFunction(),
((UriResourceFunction) resourceParts.get(0)).getParameters(), resource), path) :
getData(entity, path, resourceParts, resource);
// TODO: implement filter on collection properties (on a shallow copy of the values)
// FilterHandler.applyFilterSystemQuery(uriInfo.getFilterOption(), property, uriInfo, serviceMetadata.getEdm());
if (property == null && representationType != RepresentationType.COUNT) {
if (representationType == RepresentationType.VALUE) {
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
} else {
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
}
} else {
if (property.getValue() == null && representationType != RepresentationType.COUNT) {
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
} else {
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
if (representationType == RepresentationType.COUNT) {
response.setContent(odata.createFixedFormatSerializer().count(
property.asCollection().size()));
} else {
final EdmProperty edmProperty = path.isEmpty() ? null :
((UriResourceProperty) resourceParts.get(resourceParts.size() - trailing - 1)).getProperty();
EdmType type = null;
if (resourceParts.get(resourceParts.size() - trailing - 1)
instanceof UriResourceComplexProperty &&
((UriResourceComplexProperty)resourceParts.get(resourceParts.size() - trailing - 1)).
getComplexTypeFilter() != null) {
type = ((UriResourceComplexProperty)resourceParts.get(resourceParts.size() - trailing - 1)).
getComplexTypeFilter();
}else if(resourceParts.get(resourceParts.size() - trailing - 1)
instanceof UriResourceFunction &&
((UriResourceFunction)resourceParts.get(resourceParts.size() - trailing - 1)).
getFunction() != null){
type = ((UriResourceFunction)resourceParts.get(resourceParts.size() - trailing - 1)).
getType();
}else {
type = edmProperty == null ?
((UriResourceFunction) resourceParts.get(0)).getType() :
edmProperty.getType();
}
final EdmReturnType returnType = resourceParts.get(0) instanceof UriResourceFunction ?
((UriResourceFunction) resourceParts.get(0)).getFunction().getReturnType() :
resourceParts.get(1) instanceof UriResourceFunction ?
((UriResourceFunction) resourceParts.get(1)).getFunction().getReturnType():null ;
if (representationType == RepresentationType.VALUE) {
response.setContent(serializePrimitiveValue(property, edmProperty, (EdmPrimitiveType) type, returnType));
}else if(representationType == RepresentationType.PRIMITIVE && type.getFullQualifiedName()
.getFullQualifiedNameAsString().equals(EDMSTREAM)){
response.setContent(odata.createFixedFormatSerializer().binary(dataProvider.readStreamProperty(property)));
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, ((Link)property.getValue()).getType());
if (entity.getMediaETag() != null) {
response.setHeader(HttpHeader.ETAG, entity.getMediaETag());
}
}else {
final ExpandOption expand = uriInfo.getExpandOption();
final SelectOption select = uriInfo.getSelectOption();
final SerializerResult result = serializeProperty(entity, edmEntitySet, path, property, edmProperty,
type, returnType, representationType, contentType, expand, select);
response.setContent(result.getContent());
}
}
response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
}
if (entity != null && entity.getETag() != null) {
response.setHeader(HttpHeader.ETAG, entity.getETag());
}
}
}
private Property getData(Entity entity, List<String> path, List<UriResource> resourceParts, UriInfoResource resource)
throws DataProviderException {
if(resourceParts.size()>1 && resourceParts.get(1) instanceof UriResourceFunction){
return dataProvider.readFunctionPrimitiveComplex(((UriResourceFunction) resourceParts.get(1)).getFunction(),
((UriResourceFunction) resourceParts.get(1)).getParameters(), resource);
}
return getPropertyData(entity, path);
}
private Property getFunctionData(UriResource uriResource) {
// TODO Auto-generated method stub
return null;
}
private void updateProperty(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType requestFormat, final ContentType responseFormat, final RepresentationType representationType)
throws ODataApplicationException, ODataLibraryException {
final UriInfoResource resource = uriInfo.asUriInfoResource();
validatePath(resource);
final EdmEntitySet edmEntitySet = getEdmEntitySet(resource);
Entity entity = readEntity(uriInfo);
odata.createETagHelper().checkChangePreconditions(entity.getETag(),
request.getHeaders(HttpHeader.IF_MATCH),
request.getHeaders(HttpHeader.IF_NONE_MATCH));
final List<UriResource> resourceParts = resource.getUriResourceParts();
final int trailing = representationType == RepresentationType.VALUE ? 1 : 0;
final List<String> path = getPropertyPath(resourceParts, trailing);
final EdmProperty edmProperty = ((UriResourceProperty) resourceParts.get(resourceParts.size() - trailing - 1))
.getProperty();
Property property = getPropertyData(entity, path);
if (representationType == RepresentationType.VALUE ||
edmProperty.getType().getFullQualifiedName()
.getFullQualifiedNameAsString().equalsIgnoreCase(EDMSTREAM)) {
final FixedFormatDeserializer deserializer = odata.createFixedFormatDeserializer();
final Object value = edmProperty.getType() == odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Binary)
|| edmProperty.getType() == odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Stream) ?
deserializer.binary(request.getBody()) :
deserializer.primitiveValue(request.getBody(), edmProperty);
dataProvider.updatePropertyValue(property, value);
} else {
final Property changedProperty = odata.createDeserializer(requestFormat)
.property(request.getBody(), edmProperty).getProperty();
if (changedProperty.isNull() && !edmProperty.isNullable()) {
throw new ODataApplicationException("Not nullable.", HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
}
dataProvider.updateProperty(edmProperty, property, changedProperty, request.getMethod() == HttpMethod.PATCH);
}
dataProvider.updateETag(entity);
final Return returnPreference = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn();
if (returnPreference == null || returnPreference == Return.REPRESENTATION) {
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
if (representationType == RepresentationType.VALUE ||
edmProperty.getType().getFullQualifiedName()
.getFullQualifiedNameAsString().equalsIgnoreCase(EDMSTREAM)) {
response.setContent(
serializePrimitiveValue(property, edmProperty, (EdmPrimitiveType) edmProperty.getType(), null));
} else {
final SerializerResult result = serializeProperty(entity, edmEntitySet, path, property, edmProperty,
edmProperty.getType(), null, representationType, responseFormat, null, null);
response.setContent(result.getContent());
}
if (edmProperty.getType().getFullQualifiedName()
.getFullQualifiedNameAsString().equalsIgnoreCase(EDMSTREAM)) {
response.setHeader(HttpHeader.CONTENT_TYPE, requestFormat.toContentTypeString());
} else {
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
}
} else {
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
}
if (returnPreference != null) {
response.setHeader(HttpHeader.PREFERENCE_APPLIED,
PreferencesApplied.with().returnRepresentation(returnPreference).build().toValueString());
}
if (entity.getETag() != null) {
response.setHeader(HttpHeader.ETAG, entity.getETag());
}
}
private void deleteProperty(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final boolean isValue) throws ODataLibraryException, ODataApplicationException {
final UriInfoResource resource = uriInfo.asUriInfoResource();
validatePath(resource);
getEdmEntitySet(uriInfo); // including checks
Entity entity = readEntity(uriInfo);
odata.createETagHelper().checkChangePreconditions(entity.getETag(),
request.getHeaders(HttpHeader.IF_MATCH),
request.getHeaders(HttpHeader.IF_NONE_MATCH));
final List<UriResource> resourceParts = resource.getUriResourceParts();
final int trailing = isValue ? 1 : 0;
final List<String> path = getPropertyPath(resourceParts, trailing);
Property property = getPropertyData(entity, path);
final EdmProperty edmProperty = ((UriResourceProperty) resourceParts.get(resourceParts.size() - trailing - 1))
.getProperty();
if (edmProperty.isNullable()) {
property.setValue(property.getValueType(), edmProperty.isCollection() ? Collections.emptyList() : null);
dataProvider.updateETag(entity);
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
if (entity.getETag() != null) {
response.setHeader(HttpHeader.ETAG, entity.getETag());
}
} else {
throw new ODataApplicationException("Not nullable.", HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
}
}
private Property getPropertyData(final Entity entity, final List<String> path) {
return getPropertyData(entity.getProperty(path.get(0)), path.subList(1, path.size()));
}
private Property getPropertyData(final Property property, final List<String> path) {
Property result = property;
for (final String name : path) {
if (result != null && property.isComplex()) {
final List<Property> complex = result.asComplex().getValue();
result = null;
for (final Property innerProperty : complex) {
if (innerProperty.getName().equals(name)) {
result = innerProperty;
break;
}
}
}
}
return result;
}
private List<String> getPropertyPath(final List<UriResource> path, final int trailing) {
List<String> result = new LinkedList<String>();
int index = path.size() - trailing - 1;
while (path.get(index) instanceof UriResourceProperty) {
result.add(0, ((UriResourceProperty) path.get(index)).getProperty().getName());
index--;
}
return result;
}
private String buildPropertyPath(final List<String> path) {
StringBuilder result = new StringBuilder();
for (final String segment : path) {
result.append(result.length() == 0 ? "" : '/').append(segment);
}
return result.toString();
}
private SerializerResult serializeProperty(final Entity entity, final EdmEntitySet edmEntitySet,
final List<String> path, final Property property, final EdmProperty edmProperty,
final EdmType type, final EdmReturnType returnType,
final RepresentationType representationType, final ContentType responseFormat,
final ExpandOption expand, final SelectOption select) throws ODataLibraryException {
ODataSerializer serializer = odata.createSerializer(responseFormat);
final ContextURL contextURL = isODataMetadataNone(responseFormat) ? null :
getContextUrl(edmEntitySet, entity, path, type, representationType, expand, select);
SerializerResult result = null;
switch (representationType) {
case PRIMITIVE:
result = serializer.primitive(serviceMetadata, (EdmPrimitiveType) type, property,
PrimitiveSerializerOptions.with().contextURL(contextURL)
.nullable(edmProperty == null ? returnType.isNullable() : edmProperty.isNullable())
.maxLength(edmProperty == null ? returnType.getMaxLength() : edmProperty.getMaxLength())
.precision(edmProperty == null ? returnType.getPrecision() : edmProperty.getPrecision())
.scale(edmProperty == null ? returnType.getScale() : edmProperty.getScale())
.unicode(edmProperty == null ? null : edmProperty.isUnicode())
.build());
break;
case COMPLEX:
result = serializer.complex(serviceMetadata, (EdmComplexType) type, property,
ComplexSerializerOptions.with().contextURL(contextURL)
.expand(expand).select(select)
.build());
break;
case COLLECTION_PRIMITIVE:
result = serializer.primitiveCollection(serviceMetadata, (EdmPrimitiveType) type, property,
PrimitiveSerializerOptions.with().contextURL(contextURL)
.nullable(edmProperty == null ? returnType.isNullable() : edmProperty.isNullable())
.maxLength(edmProperty == null ? returnType.getMaxLength() : edmProperty.getMaxLength())
.precision(edmProperty == null ? returnType.getPrecision() : edmProperty.getPrecision())
.scale(edmProperty == null ? returnType.getScale() : edmProperty.getScale())
.unicode(edmProperty == null ? null : edmProperty.isUnicode())
.build());
break;
case COLLECTION_COMPLEX:
result = serializer.complexCollection(serviceMetadata, (EdmComplexType) type, property,
ComplexSerializerOptions.with().contextURL(contextURL)
.expand(expand).select(select)
.build());
break;
default:
break;
}
return result;
}
private ContextURL getContextUrl(final EdmEntitySet entitySet, final Entity entity, final List<String> path,
final EdmType type, final RepresentationType representationType,
final ExpandOption expand, final SelectOption select) throws ODataLibraryException {
final UriHelper helper = odata.createUriHelper();
Builder builder = ContextURL.with();
builder = entitySet == null ?
representationType == RepresentationType.PRIMITIVE || representationType == RepresentationType.COMPLEX ?
builder.type(type) :
builder.type(type).asCollection() :
builder.entitySet(entitySet).keyPath(helper.buildKeyPredicate(entitySet.getEntityType(), entity));
if (entitySet != null && !path.isEmpty()) {
builder = builder.navOrPropertyPath(buildPropertyPath(path));
}
builder = builder.selectList(
type.getKind() == EdmTypeKind.PRIMITIVE
|| type.getKind() == EdmTypeKind.ENUM
|| type.getKind() == EdmTypeKind.DEFINITION ?
null :
helper.buildContextURLSelectList((EdmStructuredType) type, expand, select));
return builder.build();
}
private InputStream serializePrimitiveValue(final Property property, final EdmProperty edmProperty,
final EdmPrimitiveType type, final EdmReturnType returnType) throws SerializerException {
final FixedFormatSerializer serializer = odata.createFixedFormatSerializer();
return type == odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Binary) ||
type == odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Stream) ?
serializer.binary((byte[]) property.getValue()) :
serializer.primitiveValue(type, property.getValue(),
PrimitiveValueSerializerOptions.with()
.nullable(edmProperty == null ? returnType.isNullable() : edmProperty.isNullable())
.maxLength(edmProperty == null ? returnType.getMaxLength() : edmProperty.getMaxLength())
.precision(edmProperty == null ? returnType.getPrecision() : edmProperty.getPrecision())
.scale(edmProperty == null ? returnType.getScale() : edmProperty.getScale())
.unicode(edmProperty == null ? null : edmProperty.isUnicode())
.build());
}
private void validatePath(final UriInfoResource uriInfo) throws ODataApplicationException {
final List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
for (final UriResource segment : resourcePaths.subList(1, resourcePaths.size())) {
final UriResourceKind kind = segment.getKind();
if (kind != UriResourceKind.navigationProperty
&& kind != UriResourceKind.primitiveProperty
&& kind != UriResourceKind.complexProperty
&& kind != UriResourceKind.count
&& kind != UriResourceKind.value
&& kind != UriResourceKind.function) {
throw new ODataApplicationException("Invalid resource type.",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
}
}
}