@sap/odata-v4
Version:
OData V4.0 server library
252 lines (225 loc) • 10.9 kB
JavaScript
'use strict';
const HttpMethods = require('../http/HttpMethod').Methods;
const ResourceKind = require('../uri/UriResource').ResourceKind;
const EdmTypeKind = require('../edm/EdmType').TypeKind;
const EdmPrimitiveTypeKind = require('../edm/EdmPrimitiveTypeKind');
/**
* Representation kinds with helper methods
*/
class RepresentationKind {
/**
* Determine the request representation kind for a given URI and HTTP method.
* @param {UriInfo} uriInfo OData URI information
* @param {HttpMethod.Methods} httpMethod the HTTP method
* @returns {RepresentationKind.Kinds} representation kind
*/
static getRequestRepresentationKind(uriInfo, httpMethod) {
const lastSegment = uriInfo.getLastSegment();
switch (httpMethod) {
case HttpMethods.GET:
case HttpMethods.HEAD:
case HttpMethods.DELETE:
return RepresentationKind.Kinds.NO_CONTENT;
case HttpMethods.PATCH:
switch (lastSegment.getKind()) {
case ResourceKind.ENTITY:
case ResourceKind.NAVIGATION_TO_ONE:
return RepresentationKind.Kinds.ENTITY;
case ResourceKind.COMPLEX_PROPERTY:
return RepresentationKind.Kinds.COMPLEX;
default:
return null;
}
case HttpMethods.PUT:
switch (lastSegment.getKind()) {
case ResourceKind.ENTITY:
case ResourceKind.NAVIGATION_TO_ONE:
return RepresentationKind.Kinds.ENTITY;
case ResourceKind.VALUE:
return uriInfo.getFinalEdmType() === EdmPrimitiveTypeKind.Binary ?
RepresentationKind.Kinds.BINARY :
RepresentationKind.Kinds.PRIMITIVE_VALUE;
case ResourceKind.PRIMITIVE_PROPERTY:
return uriInfo.getFinalEdmType() === EdmPrimitiveTypeKind.Stream ?
RepresentationKind.Kinds.BINARY :
RepresentationKind.Kinds.PRIMITIVE;
case ResourceKind.COMPLEX_PROPERTY:
return RepresentationKind.Kinds.COMPLEX;
case ResourceKind.PRIMITIVE_COLLECTION_PROPERTY:
return RepresentationKind.Kinds.PRIMITIVE_COLLECTION;
case ResourceKind.COMPLEX_COLLECTION_PROPERTY:
return RepresentationKind.Kinds.COMPLEX_COLLECTION;
case ResourceKind.REF:
return RepresentationKind.Kinds.REFERENCE;
default:
return null;
}
case HttpMethods.POST:
switch (lastSegment.getKind()) {
case ResourceKind.ENTITY_COLLECTION:
case ResourceKind.NAVIGATION_TO_MANY:
return RepresentationKind.Kinds.ENTITY;
case ResourceKind.REF_COLLECTION:
return RepresentationKind.Kinds.REFERENCE;
case ResourceKind.BATCH:
return RepresentationKind.Kinds.BATCH;
case ResourceKind.BOUND_ACTION:
case ResourceKind.ACTION_IMPORT:
return RepresentationKind.Kinds.ACTION_PARAMETERS;
default:
return null;
}
default:
return null;
}
}
/**
* Determine the response representation kind for a given URI and HTTP method.
* @param {UriInfo} uriInfo OData URI information
* @param {HttpMethod.Methods} httpMethod the HTTP method
* @returns {RepresentationKind.Kinds} representation kind
*/
static getResponseRepresentationKind(uriInfo, httpMethod) {
const lastSegment = uriInfo.getLastSegment();
switch (httpMethod) {
case HttpMethods.GET:
case HttpMethods.HEAD:
case HttpMethods.PATCH:
return RepresentationKind._getResponseRepresentationKindGet(uriInfo);
case HttpMethods.PUT:
if (lastSegment.getKind() === ResourceKind.REF
|| uriInfo.getFinalEdmType() === EdmPrimitiveTypeKind.Stream) {
return RepresentationKind.Kinds.NO_CONTENT;
}
return RepresentationKind._getResponseRepresentationKindGet(uriInfo);
case HttpMethods.DELETE:
return RepresentationKind.Kinds.NO_CONTENT;
case HttpMethods.POST:
switch (lastSegment.getKind()) {
case ResourceKind.ENTITY_COLLECTION:
case ResourceKind.NAVIGATION_TO_MANY:
return RepresentationKind.Kinds.ENTITY;
case ResourceKind.REF_COLLECTION:
return RepresentationKind.Kinds.NO_CONTENT;
case ResourceKind.BATCH:
return RepresentationKind.Kinds.BATCH;
case ResourceKind.ACTION_IMPORT:
case ResourceKind.BOUND_ACTION:
if (!lastSegment.getEdmType()) return RepresentationKind.Kinds.NO_CONTENT;
return RepresentationKind._createRepresentationKindFromEdmType(
lastSegment.getEdmType(), lastSegment.isCollection());
default:
return null;
}
default:
return null;
}
}
/**
* Determine the representation kind for a given URI from its resource path, assuming HTTP GET.
* @param {UriInfo} uriInfo OData URI information
* @returns {RepresentationKind.Kinds} representation kind
* @private
*/
static _getResponseRepresentationKindGet(uriInfo) {
const lastSegment = uriInfo.getLastSegment();
switch (lastSegment.getKind()) {
case ResourceKind.METADATA:
return RepresentationKind.Kinds.METADATA;
case ResourceKind.SERVICE:
return RepresentationKind.Kinds.SERVICE;
case ResourceKind.ENTITY:
case ResourceKind.SINGLETON:
case ResourceKind.NAVIGATION_TO_ONE:
return RepresentationKind.Kinds.ENTITY;
case ResourceKind.ENTITY_COLLECTION:
case ResourceKind.NAVIGATION_TO_MANY:
return RepresentationKind.Kinds.ENTITY_COLLECTION;
case ResourceKind.REF:
return RepresentationKind.Kinds.REFERENCE;
case ResourceKind.REF_COLLECTION:
return RepresentationKind.Kinds.REFERENCE_COLLECTION;
case ResourceKind.COUNT:
return RepresentationKind.Kinds.COUNT;
case ResourceKind.VALUE:
if (uriInfo.getFinalEdmType().getKind() === EdmTypeKind.ENTITY) return null;
return uriInfo.getFinalEdmType() === EdmPrimitiveTypeKind.Binary ?
RepresentationKind.Kinds.BINARY :
RepresentationKind.Kinds.PRIMITIVE_VALUE;
case ResourceKind.PRIMITIVE_PROPERTY:
return uriInfo.getFinalEdmType() === EdmPrimitiveTypeKind.Stream ?
RepresentationKind.Kinds.BINARY :
RepresentationKind.Kinds.PRIMITIVE;
case ResourceKind.COMPLEX_PROPERTY:
return RepresentationKind.Kinds.COMPLEX;
case ResourceKind.PRIMITIVE_COLLECTION_PROPERTY:
return RepresentationKind.Kinds.PRIMITIVE_COLLECTION;
case ResourceKind.COMPLEX_COLLECTION_PROPERTY:
return RepresentationKind.Kinds.COMPLEX_COLLECTION;
case ResourceKind.TYPE_CAST:
return null;
case ResourceKind.FUNCTION_IMPORT:
case ResourceKind.BOUND_FUNCTION:
return RepresentationKind._createRepresentationKindFromEdmType(
lastSegment.getEdmType(), lastSegment.isCollection());
default:
return null;
}
}
/**
* Determine the representation kind for an EDM type and the collection information.
* @param {EdmType} type Type
* @param {boolean} isCollection Type refers to a collection of that type
* @returns {RepresentationKind.Kinds} representation kind
* @private
*/
static _createRepresentationKindFromEdmType(type, isCollection) {
switch (type.getKind()) {
case EdmTypeKind.PRIMITIVE:
case EdmTypeKind.ENUM:
case EdmTypeKind.DEFINITION:
if (type === EdmPrimitiveTypeKind.Stream) return RepresentationKind.Kinds.BINARY;
return isCollection ?
RepresentationKind.Kinds.PRIMITIVE_COLLECTION :
RepresentationKind.Kinds.PRIMITIVE;
case EdmTypeKind.COMPLEX:
return isCollection ?
RepresentationKind.Kinds.COMPLEX_COLLECTION :
RepresentationKind.Kinds.COMPLEX;
case EdmTypeKind.ENTITY:
return isCollection ?
RepresentationKind.Kinds.ENTITY_COLLECTION :
RepresentationKind.Kinds.ENTITY;
default:
return null;
}
}
}
/**
* Representation kinds.
* A serializer/deserializer may be defined for the tuple representation kind, mime type
*
* @enum {string}
* @readonly
*/
RepresentationKind.Kinds = {
SERVICE: 'SERVICE', // OData JSON # 5 Service Document
ENTITY: 'ENTITY', // OData JSON # 6 Entity
PRIMITIVE: 'PRIMITIVE', // OData JSON # 7.1 Primitive Value
COMPLEX: 'COMPLEX', // OData JSON # 7.2 Complex Value
PRIMITIVE_COLLECTION: 'PRIMITIVE_COLLECTION', // OData JSON # 7.3 Collection of Primitive Values
COMPLEX_COLLECTION: 'COMPLEX_COLLECTION', // OData JSON # 7.4 Collection of Complex Values
ENTITY_COLLECTION: 'ENTITY_COLLECTION', // OData JSON # 12 Collection of Entities
ACTION_PARAMETERS: 'ACTION_PARAMETERS', // OData JSON # 17 Action Invocation
REFERENCE: 'REFERENCE', // OData JSON # 13 Entity Reference
REFERENCE_COLLECTION: 'REFERENCE_COLLECTION', // OData JSON # 13 Entity Reference
ERROR: 'ERROR', // OData JSON # 19 Error Response
DEBUG: 'DEBUG',
METADATA: 'METADATA',
COUNT: 'COUNT',
PRIMITIVE_VALUE: 'PRIMITIVE_VALUE',
BINARY: 'BINARY',
BATCH: 'BATCH',
NO_CONTENT: 'NO_CONTENT'
};
module.exports = RepresentationKind;