UNPKG

@sap/odata-v4

Version:

OData V4.0 server library

252 lines (225 loc) 10.9 kB
'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;