http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/4621d41c/JSLib/src/odata-json-light.js
----------------------------------------------------------------------
diff --git a/JSLib/src/odata-json-light.js b/JSLib/src/odata-json-light.js
deleted file mode 100644
index d963852..0000000
--- a/JSLib/src/odata-json-light.js
+++ /dev/null
@@ -1,1442 +0,0 @@
-// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
-// Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation
-// files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy,
-// modify, merge, publish, distribute, sublicense, and/or sell copies of the
Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
-
-// odata-json-light.js
-
-(function (window, undefined) {
-
- var datajs = window.odatajs || {};
- var odata = window.OData || {};
-
- // Imports
-
- var assigned = odatajs.assigned;
- var djsassert = odatajs.djsassert;
- var extend = odatajs.extend;
- var getURIInfo = odatajs.getURIInfo;
- var isArray = odatajs.isArray;
- var isDate = odatajs.isDate;
- var normalizeURI = odatajs.normalizeURI;
- var renameProperty = odatajs.renameProperty;
- var undefinedDefault = odatajs.undefinedDefault;
- var convertByteArrayToHexString = odatajs.convertByteArrayToHexString;
-
- var dataItemTypeName = odata.dataItemTypeName;
- var EDM_DATETIME = odata.EDM_DATETIME;
- var EDM_DATETIMEOFFSET = odata.EDM_DATETIMEOFFSET;
- var EDM_TIME = odata.EDM_TIME;
- var getCollectionType = odata.getCollectionType;
- var isCollection = odata.isCollection;
- var isCollectionType = odata.isCollectionType;
- var isComplex = odata.isComplex;
- var isDeferred = odata.isDeferred;
- var isFeed = odata.isFeed;
- var isEntry = odata.isEntry;
- var isGeographyEdmType = odata.isGeographyEdmType;
- var isGeometryEdmType = odata.isGeometryEdmType;
- var isPrimitiveEdmType = odata.isPrimitiveEdmType;
- var isPrimitive = odata.isPrimitive;
- var lookupComplexType = odata.lookupComplexType;
- var lookupDefaultEntityContainer = odata.lookupDefaultEntityContainer;
- var lookupEntityContainer = odata.lookupEntityContainer;
- var lookupEntitySet = odata.lookupEntitySet;
- var lookupEntityType = odata.lookupEntityType;
- var lookupFunctionImport = odata.lookupFunctionImport;
- var lookupNavigationPropertyType = odata.lookupNavigationPropertyType;
- var getEntitySetInfo = odata.getEntitySetInfo;
- var lookupNavigationPropertyEntitySet =
odata.lookupNavigationPropertyEntitySet;
- var lookupProperty = odata.lookupProperty;
- var parseBool = odata.parseBool;
- var parseDateTime = odata.parseDateTime;
- var parseDateTimeOffset = odata.parseDateTimeOffset;
- var parseDuration = odata.parseDuration;
-
- // CONTENT START
-
- var PAYLOADTYPE_OBJECT = "o";
- var PAYLOADTYPE_FEED = "f";
- var PAYLOADTYPE_PRIMITIVE = "p";
- var PAYLOADTYPE_COLLECTION = "c";
- var PAYLOADTYPE_SVCDOC = "s";
- var PAYLOADTYPE_LINKS = "l";
-
- var odataNs = "odata";
- var odataAnnotationPrefix = odataNs + ".";
-
- var contextUrlAnnotation = "@" + odataAnnotationPrefix + "context";
-
- var bindAnnotation = "@" + odataAnnotationPrefix + "bind";
- var navUrlAnnotation = odataAnnotationPrefix + "navigationLinkUrl";
- var typeAnnotation = odataAnnotationPrefix + "type";
-
- var jsonLightNameMap = {
- readLink: "self",
- editLink: "edit",
- nextLink: "__next",
- mediaReadLink: "media_src",
- mediaEditLink: "edit_media",
- mediaContentType: "content_type",
- mediaETag: "media_etag",
- count: "__count",
- media_src: "mediaReadLink",
- edit_media: "mediaEditLink",
- content_type: "mediaContentType",
- media_etag: "mediaETag",
- url: "uri"
- };
-
- var jsonLightAnnotations = {
- metadata: "odata.metadata",
- count: "odata.count",
- next: "odata.nextLink",
- id: "odata.id",
- etag: "odata.etag",
- read: "odata.readLink",
- edit: "odata.editLink",
- mediaRead: "odata.mediaReadLink",
- mediaEdit: "odata.mediaEditLink",
- mediaEtag: "odata.mediaETag",
- mediaContentType: "odata.mediaContentType",
- actions: "odata.actions",
- functions: "odata.functions",
- navigationUrl: "odata.navigationLinkUrl",
- associationUrl: "odata.associationLinkUrl",
- type: "odata.type"
- };
-
- var jsonLightAnnotationInfo = function (annotation) {
- /// <summary>Gets the name and target of an annotation in a JSON light
payload.</summary>
- /// <param name="annotation" type="String">JSON light payload
annotation.</param>
- /// <returns type="Object">Object containing the annotation name and
the target property name.</param>
-
- if (annotation.indexOf(".") > 0) {
- var targetEnd = annotation.indexOf("@");
- var target = targetEnd > -1 ? annotation.substring(0, targetEnd) :
null;
- var name = annotation.substring(targetEnd + 1);
-
- return {
- target: target,
- name: name,
- isOData: name.indexOf(odataAnnotationPrefix) === 0
- };
- }
- return null;
- };
-
- var jsonLightDataItemType = function (name, value, container,
dataItemModel, model) {
- /// <summary>Gets the type name of a JSON light data item that belongs
to a feed, an entry, a complex type property, or a collection
property.</summary>
- /// <param name="name" type="String">Name of the data item for which
the type name is going to be retrieved.</param>
- /// <param name="value">Value of the data item.</param>
- /// <param name="container" type="Object">JSON light object that owns
the data item.</param>
- /// <param name="dataItemModel" type="Object" optional="true">Object
describing the data item in an OData conceptual schema.</param>
- /// <param name="model" type="Object" optional="true">Object
describing an OData conceptual schema.</param>
- /// <remarks>
- /// This function will first try to get the type name from the data
item's value itself if it is a JSON light object; otherwise
- /// it will try to get it from the odata.type annotation applied to
the data item in the container. Then, it will fallback to the data item model.
- /// If all attempts fail, it will return null.
- /// </remarks>
- /// <returns type="String">Data item type name; null if the type name
cannot be found.</returns>
-
- return (isComplex(value) && value[typeAnnotation]) ||
- (container && container[name + "@" + typeAnnotation]) ||
- (dataItemModel && dataItemModel.type) ||
- (lookupNavigationPropertyType(dataItemModel, model)) ||
- null;
- };
-
- var jsonLightDataItemModel = function (name, containerModel) {
- /// <summary>Gets an object describing a data item in an OData
conceptual schema.</summary>
- /// <param name="name" type="String">Name of the data item for which
the model is going to be retrieved.</param>
- /// <param name="containerModel" type="Object">Object describing the
owner of the data item in an OData conceptual schema.</param>
- /// <returns type="Object">Object describing the data item; null if it
cannot be found.</returns>
-
- if (containerModel) {
- return lookupProperty(containerModel.property, name) ||
- lookupProperty(containerModel.navigationProperty, name);
- }
- return null;
- };
-
- var jsonLightIsEntry = function (data) {
- /// <summary>Determines whether data represents a JSON light entry
object.</summary>
- /// <param name="data" type="Object">JSON light object to test.</param>
- /// <returns type="Boolean">True if the data is JSON light entry
object; false otherwise.</returns>
-
- return isComplex(data) && ((odataAnnotationPrefix + "id") in data);
- };
-
- var jsonLightIsNavigationProperty = function (name, data, dataItemModel) {
- /// <summary>Determines whether a data item in a JSON light object is
a navigation property.</summary>
- /// <param name="name" type="String">Name of the data item to
test.</param>
- /// <param name="data" type="Object">JSON light object that owns the
data item.</param>
- /// <param name="dataItemModel" type="Object">Object describing the
data item in an OData conceptual schema.</param>
- /// <returns type="Boolean">True if the data item is a navigation
property; false otherwise.</returns>
-
- djsassert(isComplex(data), "jsonLightIsNavProp - data is not an
object!!");
- if (!!data[name + "@" + navUrlAnnotation] || (dataItemModel &&
dataItemModel.relationship)) {
- return true;
- }
-
- // Sniff the property value.
- var value = isArray(data[name]) ? data[name][0] : data[name];
- return jsonLightIsEntry(value);
- };
-
- var jsonLightIsPrimitiveType = function (typeName) {
- /// <summary>Determines whether a type name is a primitive type in a
JSON light payload.</summary>
- /// <param name="typeName" type="String">Type name to test.</param>
- /// <returns type="Boolean">True if the type name an EDM primitive
type or an OData spatial type; false otherwise.</returns>
-
- return isPrimitiveEdmType(typeName) || isGeographyEdmType(typeName) ||
isGeometryEdmType(typeName);
- };
-
- var jsonLightReadDataAnnotations = function (data, obj, baseURI,
dataModel, model) {
- /// <summary>Converts annotations found in a JSON light payload object
to either properties or metadata.</summary>
- /// <param name="data" type="Object">JSON light payload object
containing the annotations to convert.</param>
- /// <param name="obj" type="Object">Object that will store the
converted annotations.</param>
- /// <param name="baseURI" type="String">Base URI for normalizing
relative URIs found in the payload.</param>
- /// <param name="dataModel" type="Object">Object describing the JSON
light payload in an OData conceptual schema.</param>
- /// <param name="model" type="Object" optional="true">Object
describing an OData conceptual schema.</param>
- /// <returns>JSON light payload object with its annotations converted
to either properties or metadata.</param>
-
- for (var name in data) {
- if (name.indexOf(".") > 0 && name.charAt(0) !== "#") {
- var annotationInfo = jsonLightAnnotationInfo(name);
- if (annotationInfo) {
- var annotationName = annotationInfo.name;
- var target = annotationInfo.target;
- var targetModel = null;
- var targetType = null;
-
- if (target) {
- targetModel = jsonLightDataItemModel(target,
dataModel);
- targetType = jsonLightDataItemType(target,
data[target], data, targetModel, model);
- }
-
- if (annotationInfo.isOData) {
- jsonLightApplyPayloadODataAnnotation(annotationName,
target, targetType, data[name], data, obj, baseURI);
- } else {
- obj[name] = data[name];
- }
- }
- }
- }
- return obj;
- };
-
- var jsonLightApplyPayloadODataAnnotation = function (name, target,
targetType, value, data, obj, baseURI) {
- /// <summary>
- /// Processes a JSON Light payload OData annotation producing either
a property, payload metadata, or property metadata on its owner object.
- /// </summary>
- /// <param name="name" type="String">Annotation name.</param>
- /// <param name="target" type="String">Name of the property that is
being targeted by the annotation.</param>
- /// <param name="targetType" type="String">Type name of the target
property.</param>
- /// <param name="data" type="Object">JSON light object containing the
annotation.</param>
- /// <param name="obj" type="Object">Object that will hold properties
produced by the annotation.</param>
- /// <param name="baseURI" type="String">Base URI for normalizing
relative URIs found in the payload.</param>
-
- var annotation = name.substring(odataAnnotationPrefix.length);
-
- switch (annotation) {
- case "navigationLinkUrl":
- jsonLightApplyNavigationUrlAnnotation(annotation, target,
targetType, value, data, obj, baseURI);
- return;
- case "nextLink":
- case "count":
- jsonLightApplyFeedAnnotation(annotation, target, value, obj,
baseURI);
- return;
- case "mediaReadLink":
- case "mediaEditLink":
- case "mediaContentType":
- case "mediaETag":
- jsonLightApplyMediaAnnotation(annotation, target, targetType,
value, obj, baseURI);
- return;
- default:
- jsonLightApplyMetadataAnnotation(annotation, target, value,
obj, baseURI);
- return;
- }
- };
-
- var jsonLightApplyMetadataAnnotation = function (name, target, value, obj,
baseURI) {
- /// <summary>
- /// Converts a JSON light annotation that applies to entry metadata
only (i.e. odata.editLink or odata.readLink) and its value
- /// into their library's internal representation and saves it back
to data.
- /// </summary>
- /// <param name="name" type="String">Annotation name.</param>
- /// <param name="target" type="String">Name of the property on which
the annotation should be applied.</param>
- /// <param name="value" type="Object">Annotation value.</param>
- /// <param name="obj" type="Object">Object that will hold properties
produced by the annotation.</param>
- /// <param name="baseURI" type="String">Base URI for normalizing
relative URIs found in the payload.</param>
-
- var metadata = obj.__metadata = obj.__metadata || {};
- var mappedName = jsonLightNameMap[name] || name;
-
- if (name === "editLink") {
- metadata.uri = normalizeURI(value, baseURI);
- metadata[mappedName] = metadata.uri;
- return;
- }
-
- if (name === "readLink" || name === "associationLinkUrl") {
- value = normalizeURI(value, baseURI);
- }
-
- if (target) {
- var propertiesMetadata = metadata.properties = metadata.properties
|| {};
- var propertyMetadata = propertiesMetadata[target] =
propertiesMetadata[target] || {};
-
- if (name === "type") {
- propertyMetadata[mappedName] = propertyMetadata[mappedName] ||
value;
- return;
- }
- propertyMetadata[mappedName] = value;
- return;
- }
- metadata[mappedName] = value;
- };
-
- var jsonLightApplyFeedAnnotation = function (name, target, value, obj,
baseURI) {
- /// <summary>
- /// Converts a JSON light annotation that applies to feeds only
(i.e. odata.count or odata.nextlink) and its value
- /// into their library's internal representation and saves it back
to data.
- /// </summary>
- /// <param name="name" type="String">Annotation name.</param>
- /// <param name="target" type="String">Name of the property on which
the annotation should be applied.</param>
- /// <param name="value" type="Object">Annotation value.</param>
- /// <param name="obj" type="Object">Object that will hold properties
produced by the annotation.</param>
- /// <param name="baseURI" type="String">Base URI for normalizing
relative URIs found in the payload.</param>
-
- var mappedName = jsonLightNameMap[name];
- var feed = target ? obj[target] : obj;
- feed[mappedName] = (name === "nextLink") ? normalizeURI(value,
baseURI) : value;
- };
-
- var jsonLightApplyMediaAnnotation = function (name, target, targetType,
value, obj, baseURI) {
- /// <summary>
- /// Converts a JSON light media annotation in and its value into
their library's internal representation
- /// and saves it back to data or metadata.
- /// </summary>
- /// <param name="name" type="String">Annotation name.</param>
- /// <param name="target" type="String">Name of the property on which
the annotation should be applied.</param>
- /// <param name="targetType" type="String">Type name of the target
property.</param>
- /// <param name="value" type="Object">Annotation value.</param>
- /// <param name="obj" type="Object">Object that will hold properties
produced by the annotation.</param>
- /// <param name="baseURI" type="String">Base URI for normalizing
relative URIs found in the payload.</param>
-
- var metadata = obj.__metadata = obj.__metadata || {};
- var mappedName = jsonLightNameMap[name];
-
- if (name === "mediaReadLink" || name === "mediaEditLink") {
- value = normalizeURI(value, baseURI);
- }
-
- if (target) {
- var propertiesMetadata = metadata.properties = metadata.properties
|| {};
- var propertyMetadata = propertiesMetadata[target] =
propertiesMetadata[target] || {};
- propertyMetadata.type = propertyMetadata.type || targetType;
-
- obj.__metadata = metadata;
- obj[target] = obj[target] || { __mediaresource: {} };
- obj[target].__mediaresource[mappedName] = value;
- return;
- }
-
- metadata[mappedName] = value;
- };
-
- var jsonLightApplyNavigationUrlAnnotation = function (name, target,
targetType, value, data, obj, baseURI) {
- /// <summary>
- /// Converts a JSON light navigation property annotation and its
value into their library's internal representation
- /// and saves it back to data o metadata.
- /// </summary>
- /// <param name="name" type="String">Annotation name.</param>
- /// <param name="target" type="String">Name of the property on which
the annotation should be applied.</param>
- /// <param name="targetType" type="String">Type name of the target
property.</param>
- /// <param name="value" type="Object">Annotation value.</param>
- /// <param name="data" type="Object">JSON light object containing the
annotation.</param>
- /// <param name="obj" type="Object">Object that will hold properties
produced by the annotation.</param>
- /// <param name="baseURI" type="String">Base URI for normalizing
relative URIs found in the payload.</param>
-
- var metadata = obj.__metadata = obj.__metadata || {};
- var propertiesMetadata = metadata.properties = metadata.properties ||
{};
- var propertyMetadata = propertiesMetadata[target] =
propertiesMetadata[target] || {};
- var uri = normalizeURI(value, baseURI);
-
- if (data.hasOwnProperty(target)) {
- // The navigation property is inlined in the payload,
- // so the navigation link url should be pushed to the object's
- // property metadata instead.
- propertyMetadata.navigationLinkUrl = uri;
- return;
- }
- obj[target] = { __deferred: { uri: uri} };
- propertyMetadata.type = propertyMetadata.type || targetType;
- };
-
-
- var jsonLightReadDataItemValue = function (value, typeName,
dataItemMetadata, baseURI, dataItemModel, model, recognizeDates) {
- /// <summary>Converts the value of a data item in a JSON light object
to its library representation.</summary>
- /// <param name="value">Data item value to convert.</param>
- /// <param name="typeName" type="String">Type name of the data
item.</param>
- /// <param name="dataItemMetadata" type="Object">Object containing
metadata about the data item.</param>
- /// <param name="baseURI" type="String">Base URI for normalizing
relative URIs found in the payload.</param>
- /// <param name="dataItemModel" type="Object" optional="true">Object
describing the data item in an OData conceptual schema.</param>
- /// <param name="model" type="Object" optional="true">Object
describing an OData conceptual schema.</param>
- /// <param name="recognizeDates" type="Boolean" optional="true">Flag
indicating whether datetime literal strings should be converted to JavaScript
Date objects.</param>
- /// <returns>Data item value in its library representation.</param>
-
- if (typeof value === "string") {
- return jsonLightReadStringPropertyValue(value, typeName,
recognizeDates);
- }
-
- if (!jsonLightIsPrimitiveType(typeName)) {
- if (isArray(value)) {
- return jsonLightReadCollectionPropertyValue(value, typeName,
dataItemMetadata, baseURI, model, recognizeDates);
- }
-
- if (isComplex(value)) {
- return jsonLightReadComplexPropertyValue(value, typeName,
dataItemMetadata, baseURI, model, recognizeDates);
- }
- }
- return value;
- };
-
- var jsonLightReadStringPropertyValue = function (value, propertyType,
recognizeDates) {
- /// <summary>Convertes the value of a string property in a JSON light
object to its library representation.</summary>
- /// <param name="value" type="String">String value to convert.</param>
- /// <param name="propertyType" type="String">Type name of the
property.</param>
- /// <param name="recognizeDates" type="Boolean" optional="true">Flag
indicating whether datetime literal strings should be converted to JavaScript
Date objects.</param>
- /// <returns>String property value in its library
representation.</returns>
-
- switch (propertyType) {
- case EDM_TIME:
- return parseDuration(value);
- case EDM_DATETIME:
- return parseDateTime(value, /*nullOnError*/false);
- case EDM_DATETIMEOFFSET:
- return parseDateTimeOffset(value, /*nullOnError*/false);
- }
-
- if (recognizeDates) {
- return parseDateTime(value, /*nullOnError*/true) ||
- parseDateTimeOffset(value, /*nullOnError*/true) ||
- value;
- }
- return value;
- };
-
- var jsonLightReadCollectionPropertyValue = function (value, propertyType,
propertyMetadata, baseURI, model, recognizeDates) {
- /// <summary>Converts the value of a collection property in a JSON
light object into its library representation.</summary>
- /// <param name="value" type="Array">Collection property value to
convert.</param>
- /// <param name="propertyType" type="String">Property type
name.</param>
- /// <param name="propertyMetadata" type="Object">Object containing
metadata about the collection property.</param>
- /// <param name="baseURI" type="String">Base URI for normalizing
relative URIs found in the payload.</param>
- /// <param name="model" type="Object" optional="true">Object
describing an OData conceptual schema.</param>
- /// <param name="recognizeDates" type="Boolean" optional="true">Flag
indicating whether datetime literal strings should be converted to JavaScript
Date objects.</param>
- /// <returns type="Object">Collection property value in its library
representation.</returns>
-
- var collectionType = getCollectionType(propertyType);
- var itemsMetadata = [];
- var items = [];
-
- var i, len;
- for (i = 0, len = value.length; i < len; i++) {
- var itemType = jsonLightDataItemType(null, value[i]) ||
collectionType;
- var itemMetadata = { type: itemType };
- var item = jsonLightReadDataItemValue(value[i], itemType,
itemMetadata, baseURI, null, model, recognizeDates);
-
- if (!jsonLightIsPrimitiveType(itemType) && !isPrimitive(value[i]))
{
- itemsMetadata.push(itemMetadata);
- }
- items.push(item);
- }
-
- if (itemsMetadata.length > 0) {
- propertyMetadata.elements = itemsMetadata;
- }
-
- return { __metadata: { type: propertyType }, results: items };
- };
-
- var jsonLightReadComplexPropertyValue = function (value, propertyType,
propertyMetadata, baseURI, model, recognizeDates) {
- /// <summary>Converts the value of a comples property in a JSON light
object into its library representation.</summary>
- /// <param name="value" type="Object">Complex property value to
convert.</param>
- /// <param name="propertyType" type="String">Property type
name.</param>
- /// <param name="propertyMetadata" type="Object">Object containing
metadata about the complx type property.</param>
- /// <param name="baseURI" type="String">Base URI for normalizing
relative URIs found in the payload.</param>
- /// <param name="model" type="Object" optional="true">Object
describing an OData conceptual schema.</param>
- /// <param name="recognizeDates" type="Boolean" optional="true">Flag
indicating whether datetime literal strings should be converted to JavaScript
Date objects.</param>
- /// <returns type="Object">Complex property value in its library
representation.</returns>
-
- var complexValue = jsonLightReadObject(value, { type: propertyType },
baseURI, model, recognizeDates);
- var complexMetadata = complexValue.__metadata;
- var complexPropertiesMetadata = complexMetadata.properties;
-
- if (complexPropertiesMetadata) {
- propertyMetadata.properties = complexPropertiesMetadata;
- delete complexMetadata.properties;
- }
- return complexValue;
- };
-
- var jsonLightReadNavigationPropertyValue = function (value, propertyInfo,
baseURI, model, recognizeDates) {
- /// <summary>Converts the value of a navigation property in a JSON
light object into its library representation.</summary>
- /// <param name="value">Navigation property property value to
convert.</param>
- /// <param name="propertyInfo" type="String">Information about the
property whether it's an entry, feed or complex type.</param>
- /// <param name="baseURI" type="String">Base URI for normalizing
relative URIs found in the payload.</param>
- /// <param name="model" type="Object" optional="true">Object
describing an OData conceptual schema.</param>
- /// <param name="recognizeDates" type="Boolean" optional="true">Flag
indicating whether datetime literal strings should be converted to JavaScript
Date objects.</param>
- /// <returns type="Object">Collection property value in its library
representation.</returns>
-
- if (isArray(value)) {
- return jsonLightReadFeed(value, propertyInfo, baseURI, model,
recognizeDates);
- }
-
- if (isComplex(value)) {
- return jsonLightReadObject(value, propertyInfo, baseURI, model,
recognizeDates);
- }
- return null;
- };
-
- var jsonLightReadObject = function (data, objectInfo, baseURI, model,
recognizeDates) {
- /// <summary>Converts a JSON light entry or complex type object into
its library representation.</summary>
- /// <param name="data" type="Object">JSON light entry or complex type
object to convert.</param>
- /// <param name="objectInfo" type="Object">Information about the entry
or complex.</param>
- /// <param name="baseURI" type="String">Base URI for normalizing
relative URIs found in the payload.</param>
- /// <param name="model" type="Object" optional="true">Object
describing an OData conceptual schema.</param>
- /// <param name="recognizeDates" type="Boolean" optional="true">Flag
indicating whether datetime literal strings should be converted to JavaScript
Date objects.</param>
- /// <returns type="Object">Entry or complex type object.</param>
-
- objectInfo = objectInfo || {};
- var actualType = data[typeAnnotation] || objectInfo.type || null;
- var dataModel = lookupEntityType(actualType, model);
- var isEntry = true;
- if (!dataModel) {
- isEntry = false;
- dataModel = lookupComplexType(actualType, model);
- }
-
- var metadata = { type: actualType };
- var obj = { __metadata: metadata };
- var propertiesMetadata = {};
- var baseTypeModel;
- if (isEntry && dataModel && objectInfo.entitySet &&
objectInfo.contentTypeOdata == "minimalmetadata") {
- var serviceURI = baseURI.substring(0,
baseURI.lastIndexOf("$metadata"));
- baseTypeModel = null; // check if the key model is in a parent
type.
- if (!dataModel.key) {
- baseTypeModel = dataModel;
- }
- while (!!baseTypeModel && !baseTypeModel.key &&
baseTypeModel.baseType) {
- baseTypeModel = lookupEntityType(baseTypeModel.baseType,
model);
- }
-
- if (dataModel.key || (!!baseTypeModel && baseTypeModel.key)) {
- var entryKey;
- if (dataModel.key) {
- entryKey = jsonLightGetEntryKey(data, dataModel);
- } else {
- entryKey = jsonLightGetEntryKey(data, baseTypeModel);
- }
- if (entryKey) {
- var entryInfo = {
- key: entryKey,
- entitySet: objectInfo.entitySet,
- functionImport: objectInfo.functionImport,
- containerName: objectInfo.containerName
- };
- jsonLightComputeUrisIfMissing(data, entryInfo, actualType,
serviceURI, dataModel, baseTypeModel);
- }
- }
- }
-
- for (var name in data) {
- if (name.indexOf("#") === 0) {
- // This is an advertised function or action.
- jsonLightReadAdvertisedFunctionOrAction(name.substring(1),
data[name], obj, baseURI, model);
- } else {
- // Is name NOT an annotation?
- if (name.indexOf(".") === -1) {
- if (!metadata.properties) {
- metadata.properties = propertiesMetadata;
- }
-
- var propertyValue = data[name];
- var propertyModel = propertyModel =
jsonLightDataItemModel(name, dataModel);
- baseTypeModel = dataModel;
- while (!!dataModel && propertyModel === null &&
baseTypeModel.baseType) {
- baseTypeModel =
lookupEntityType(baseTypeModel.baseType, model);
- propertyModel = propertyModel =
jsonLightDataItemModel(name, baseTypeModel);
- }
- var isNavigationProperty =
jsonLightIsNavigationProperty(name, data, propertyModel);
- var propertyType = jsonLightDataItemType(name,
propertyValue, data, propertyModel, model);
- var propertyMetadata = propertiesMetadata[name] =
propertiesMetadata[name] || { type: propertyType };
- if (isNavigationProperty) {
- var propertyInfo = {};
- if (objectInfo.entitySet !== undefined) {
- var navigationPropertyEntitySetName =
lookupNavigationPropertyEntitySet(propertyModel, objectInfo.entitySet.name,
model);
- propertyInfo =
getEntitySetInfo(navigationPropertyEntitySetName, model);
- }
- propertyInfo.contentTypeOdata =
objectInfo.contentTypeOdata;
- propertyInfo.kind = objectInfo.kind;
- propertyInfo.type = propertyType;
- obj[name] =
jsonLightReadNavigationPropertyValue(propertyValue, propertyInfo, baseURI,
model, recognizeDates);
- } else {
- obj[name] = jsonLightReadDataItemValue(propertyValue,
propertyType, propertyMetadata, baseURI, propertyModel, model, recognizeDates);
- }
- }
- }
- }
-
- return jsonLightReadDataAnnotations(data, obj, baseURI, dataModel,
model);
- };
-
- var jsonLightReadAdvertisedFunctionOrAction = function (name, value, obj,
baseURI, model) {
- /// <summary>Converts a JSON light advertised action or function
object into its library representation.</summary>
- /// <param name="name" type="String">Advertised action or function
name.</param>
- /// <param name="value">Advertised action or function value.</param>
- /// <param name="obj" type="Object">Object that will the converted
value of the advertised action or function.</param>
- /// <param name="baseURI" type="String">Base URI for normalizing the
action's or function's relative URIs.</param>
- /// <param name="model" type="Object" optional="true">Object
describing an OData conceptual schema.</param>
- /// <remarks>
- /// Actions and functions have the same representation in json
light, so to disambiguate them the function uses
- /// the model object. If available, the function will look for
the functionImport object that describes the
- /// the action or the function. If for whatever reason the
functionImport can't be retrieved from the model (like
- /// there is no model available or there is no functionImport
within the model), then the value is going to be treated
- /// as an advertised action and stored under
obj.__metadata.actions.
- /// </remarks>
-
- if (!name || !isArray(value) && !isComplex(value)) {
- return;
- }
-
- var isFunction = false;
- var nsEnd = name.lastIndexOf(".");
- var simpleName = name.substring(nsEnd + 1);
- var containerName = (nsEnd > -1) ? name.substring(0, nsEnd) : "";
-
- var container = (simpleName === name || containerName.indexOf(".") ===
-1) ?
- lookupDefaultEntityContainer(model) :
- lookupEntityContainer(containerName, model);
-
- if (container) {
- var functionImport =
lookupFunctionImport(container.functionImport, simpleName);
- if (functionImport && !!functionImport.isSideEffecting) {
- isFunction = !parseBool(functionImport.isSideEffecting);
- }
- }
-
- var metadata = obj.__metadata;
- var targetName = isFunction ? "functions" : "actions";
- var metadataURI = normalizeURI(name, baseURI);
- var items = (isArray(value)) ? value : [value];
-
- var i, len;
- for (i = 0, len = items.length; i < len; i++) {
- var item = items[i];
- if (item) {
- var targetCollection = metadata[targetName] =
metadata[targetName] || [];
- var actionOrFunction = { metadata: metadataURI, title:
item.title, target: normalizeURI(item.target, baseURI) };
- targetCollection.push(actionOrFunction);
- }
- }
- };
-
- var jsonLightReadFeed = function (data, feedInfo, baseURI, model,
recognizeDates) {
- /// <summary>Converts a JSON light feed or top level collection
property object into its library representation.</summary>
- /// <param name="data" type="Object">JSON light feed object to
convert.</param>
- /// <param name="typeName" type="String">Type name of the feed or
collection items.</param>
- /// <param name="baseURI" type="String">Base URI for normalizing
relative URIs found in the payload.</param>
- /// <param name="model" type="Object" optional="true">Object
describing an OData conceptual schema.</param>
- /// <param name="recognizeDates" type="Boolean" optional="true">Flag
indicating whether datetime literal strings should be converted to JavaScript
Date objects.</param>
- /// <returns type="Object">Feed or top level collection object.</param>
-
- var items = isArray(data) ? data : data.value;
- var entries = [];
- var i, len, entry;
- for (i = 0, len = items.length; i < len; i++) {
- entry = jsonLightReadObject(items[i], feedInfo, baseURI, model,
recognizeDates);
- entries.push(entry);
- }
-
- var feed = { results: entries };
-
- if (isComplex(data)) {
- for (var name in data) {
- if (name.indexOf("#") === 0) {
- // This is an advertised function or action.
- feed.__metadata = feed.__metadata || {};
- jsonLightReadAdvertisedFunctionOrAction(name.substring(1),
data[name], feed, baseURI, model);
- }
- }
- feed = jsonLightReadDataAnnotations(data, feed, baseURI);
- }
- return feed;
- };
-
- var jsonLightGetEntryKey = function (data, entityModel) {
- /// <summary>Gets the key of an entry.</summary>
- /// <param name="data" type="Object">JSON light entry.</param>
- /// <param name="entityModel" type="String">Object describing the
entry Model</param>
- /// <returns type="string">Entry instance key.</returns>
-
- var entityInstanceKey;
- var entityKeys = entityModel.key.propertyRef;
- var type;
- entityInstanceKey = "(";
- if (entityKeys.length == 1) {
- type = lookupProperty(entityModel.property,
entityKeys[0].name).type;
- entityInstanceKey += formatLiteral(data[entityKeys[0].name], type);
- } else {
- var first = true;
- for (var i = 0; i < entityKeys.length; i++) {
- if (!first) {
- entityInstanceKey += ",";
- } else {
- first = false;
- }
- type = lookupProperty(entityModel.property,
entityKeys[i].name).type;
- entityInstanceKey += entityKeys[i].name + "=" +
formatLiteral(data[entityKeys[i].name], type);
- }
- }
- entityInstanceKey += ")";
- return entityInstanceKey;
- };
-
-
- var jsonLightComputeUrisIfMissing = function (data, entryInfo, actualType,
serviceURI, entityModel, baseTypeModel) {
- /// <summary>Compute the URI according to OData conventions if it
doesn't exist</summary>
- /// <param name="data" type="Object">JSON light entry.</param>
- /// <param name="entryInfo" type="Object">Information about the entry
includes type, key, entitySet and entityContainerName.</param>
- /// <param name="actualType" type="String">Type of the entry</param>
- /// <param name="serviceURI" type="String">Base URI the
service.</param>
- /// <param name="entityModel" type="Object">Object describing an OData
conceptual schema of the entry.</param>
- /// <param name="baseTypeModel" type="Object" optional="true">Object
escribing an OData conceptual schema of the baseType if it exists.</param>
-
- var lastIdSegment = data[jsonLightAnnotations.id] ||
data[jsonLightAnnotations.read] || data[jsonLightAnnotations.edit] ||
entryInfo.entitySet.name + entryInfo.key;
- data[jsonLightAnnotations.id] = serviceURI + lastIdSegment;
- if (!data[jsonLightAnnotations.edit]) {
- data[jsonLightAnnotations.edit] = entryInfo.entitySet.name +
entryInfo.key;
- if (entryInfo.entitySet.entityType != actualType) {
- data[jsonLightAnnotations.edit] += "/" + actualType;
- }
- }
- data[jsonLightAnnotations.read] = data[jsonLightAnnotations.read] ||
data[jsonLightAnnotations.edit];
- if (!data[jsonLightAnnotations.etag]) {
- var etag = jsonLightComputeETag(data, entityModel, baseTypeModel);
- if (!!etag) {
- data[jsonLightAnnotations.etag] = etag;
- }
- }
-
- jsonLightComputeStreamLinks(data, entityModel, baseTypeModel);
- jsonLightComputeNavigationAndAssociationProperties(data, entityModel,
baseTypeModel);
- jsonLightComputeFunctionImports(data, entryInfo);
- };
-
- var jsonLightComputeETag = function (data, entityModel, baseTypeModel) {
- /// <summary>Computes the etag of an entry</summary>
- /// <param name="data" type="Object">JSON light entry.</param>
- /// <param name="entryInfo" type="Object">Object describing the entry
model.</param>
- /// <param name="baseTypeModel" type="Object" optional="true">Object
describing an OData conceptual schema of the baseType if it exists.</param>
- /// <returns type="string">Etag value</returns>
- var etag = "";
- var propertyModel;
- for (var i = 0; entityModel.property && i <
entityModel.property.length; i++) {
- propertyModel = entityModel.property[i];
- etag = jsonLightAppendValueToEtag(data, etag, propertyModel);
-
- }
- if (baseTypeModel) {
- for (i = 0; baseTypeModel.property && i <
baseTypeModel.property.length; i++) {
- propertyModel = baseTypeModel.property[i];
- etag = jsonLightAppendValueToEtag(data, etag, propertyModel);
- }
- }
- if (etag.length > 0) {
- return etag + "\"";
- }
- return null;
- };
-
- var jsonLightAppendValueToEtag = function (data, etag, propertyModel) {
- /// <summary>Adds a propery value to the etag after
formatting.</summary>
- /// <param name="data" type="Object">JSON light entry.</param>
- /// <param name="etag" type="Object">value of the etag.</param>
- /// <param name="propertyModel" type="Object">Object describing an
OData conceptual schema of the property.</param>
- /// <returns type="string">Etag value</returns>
-
- if (propertyModel.concurrencyMode == "Fixed") {
- if (etag.length > 0) {
- etag += ",";
- } else {
- etag += "W/\"";
- }
- if (data[propertyModel.name] !== null) {
- etag += formatLiteral(data[propertyModel.name],
propertyModel.type);
- } else {
- etag += "null";
- }
- }
- return etag;
- };
-
- var jsonLightComputeNavigationAndAssociationProperties = function (data,
entityModel, baseTypeModel) {
- /// <summary>Adds navigation links to the entry metadata</summary>
- /// <param name="data" type="Object">JSON light entry.</param>
- /// <param name="entityModel" type="Object">Object describing the
entry model.</param>
- /// <param name="baseTypeModel" type="Object" optional="true">Object
describing an OData conceptual schema of the baseType if it exists.</param>
-
- var navigationLinkAnnotation = "@odata.navigationLinkUrl";
- var associationLinkAnnotation = "@odata.associationLinkUrl";
- var navigationPropertyName, navigationPropertyAnnotation,
associationPropertyAnnotation;
- for (var i = 0; entityModel.navigationProperty && i <
entityModel.navigationProperty.length; i++) {
- navigationPropertyName = entityModel.navigationProperty[i].name;
- navigationPropertyAnnotation = navigationPropertyName +
navigationLinkAnnotation;
- if (data[navigationPropertyAnnotation] === undefined) {
- data[navigationPropertyAnnotation] =
data[jsonLightAnnotations.edit] + "/" +
encodeURIComponent(navigationPropertyName);
- }
- associationPropertyAnnotation = navigationPropertyName +
associationLinkAnnotation;
- if (data[associationPropertyAnnotation] === undefined) {
- data[associationPropertyAnnotation] =
data[jsonLightAnnotations.edit] + "/$links/" +
encodeURIComponent(navigationPropertyName);
- }
- }
-
- if (baseTypeModel && baseTypeModel.navigationProperty) {
- for (i = 0; i < baseTypeModel.navigationProperty.length; i++) {
- navigationPropertyName =
baseTypeModel.navigationProperty[i].name;
- navigationPropertyAnnotation = navigationPropertyName +
navigationLinkAnnotation;
- if (data[navigationPropertyAnnotation] === undefined) {
- data[navigationPropertyAnnotation] =
data[jsonLightAnnotations.edit] + "/" +
encodeURIComponent(navigationPropertyName);
- }
- associationPropertyAnnotation = navigationPropertyName +
associationLinkAnnotation;
- if (data[associationPropertyAnnotation] === undefined) {
- data[associationPropertyAnnotation] =
data[jsonLightAnnotations.edit] + "/$links/" +
encodeURIComponent(navigationPropertyName);
- }
- }
- }
- };
-
- var formatLiteral = function (value, type) {
- /// <summary>Formats a value according to Uri literal format</summary>
- /// <param name="value">Value to be formatted.</param>
- /// <param name="type">Edm type of the value</param>
- /// <returns type="string">Value after formatting</returns>
-
- value = "" + formatRowLiteral(value, type);
- value = encodeURIComponent(value.replace("'", "''"));
- switch ((type)) {
- case "Edm.Binary":
- return "X'" + value + "'";
- case "Edm.DateTime":
- return "datetime" + "'" + value + "'";
- case "Edm.DateTimeOffset":
- return "datetimeoffset" + "'" + value + "'";
- case "Edm.Decimal":
- return value + "M";
- case "Edm.Guid":
- return "guid" + "'" + value + "'";
- case "Edm.Int64":
- return value + "L";
- case "Edm.Float":
- return value + "f";
- case "Edm.Double":
- return value + "D";
- case "Edm.Geography":
- return "geography" + "'" + value + "'";
- case "Edm.Geometry":
- return "geometry" + "'" + value + "'";
- case "Edm.Time":
- return "time" + "'" + value + "'";
- case "Edm.String":
- return "'" + value + "'";
- default:
- return value;
- }
- };
-
-
- var formatRowLiteral = function (value, type) {
- switch (type) {
- case "Edm.Binary":
- return convertByteArrayToHexString(value);
- default:
- return value;
- }
- };
-
- var jsonLightComputeFunctionImports = function (data, entryInfo) {
- /// <summary>Adds functions and actions links to the entry
metadata</summary>
- /// <param name="entry" type="Object">JSON light entry.</param>
- /// <param name="entityInfo" type="Object">Object describing the
entry</param>
-
- var functionImport = entryInfo.functionImport || [];
- for (var i = 0; i < functionImport.length; i++) {
- if (functionImport[i].isBindable && functionImport[i].parameter[0]
&& functionImport[i].parameter[0].type == entryInfo.entitySet.entityType) {
- var functionImportAnnotation = "#" + entryInfo.containerName +
"." + functionImport[i].name;
- if (data[functionImportAnnotation] == undefined) {
- data[functionImportAnnotation] = {
- title: functionImport[i].name,
- target: data[jsonLightAnnotations.edit] + "/" +
functionImport[i].name
- };
- }
- }
- }
- };
-
- var jsonLightComputeStreamLinks = function (data, entityModel,
baseTypeModel) {
- /// <summary>Adds stream links to the entry metadata</summary>
- /// <param name="data" type="Object">JSON light entry.</param>
- /// <param name="entityModel" type="Object">Object describing the
entry model.</param>
- /// <param name="baseTypeModel" type="Object" optional="true">Object
describing an OData conceptual schema of the baseType if it exists.</param>
-
- if (entityModel.hasStream || (baseTypeModel &&
baseTypeModel.hasStream)) {
- data[jsonLightAnnotations.mediaEdit] =
data[jsonLightAnnotations.mediaEdit] || data[jsonLightAnnotations.mediaEdit] +
"/$value";
- data[jsonLightAnnotations.mediaRead] =
data[jsonLightAnnotations.mediaRead] || data[jsonLightAnnotations.mediaEdit];
- }
- };
-
- var jsonLightReadTopPrimitiveProperty = function (data, typeName, baseURI,
recognizeDates) {
- /// <summary>Converts a JSON light top level primitive property object
into its library representation.</summary>
- /// <param name="data" type="Object">JSON light feed object to
convert.</param>
- /// <param name="typeName" type="String">Type name of the primitive
property.</param>
- /// <param name="baseURI" type="String">Base URI for normalizing
relative URIs found in the payload.</param>
- /// <param name="recognizeDates" type="Boolean" optional="true">Flag
indicating whether datetime literal strings should be converted to JavaScript
Date objects.</param>
- /// <returns type="Object">Top level primitive property object.</param>
-
- var metadata = { type: typeName };
- var value = jsonLightReadDataItemValue(data.value, typeName, metadata,
baseURI, null, null, recognizeDates);
- return jsonLightReadDataAnnotations(data, { __metadata: metadata,
value: value }, baseURI);
- };
-
- var jsonLightReadTopCollectionProperty = function (data, typeName,
baseURI, model, recognizeDates) {
- /// <summary>Converts a JSON light top level collection property
object into its library representation.</summary>
- /// <param name="data" type="Object">JSON light feed object to
convert.</param>
- /// <param name="typeName" type="String">Type name of the collection
property.</param>
- /// <param name="baseURI" type="String">Base URI for normalizing
relative URIs found in the payload.</param>
- /// <param name="model" type="Object" optional="true">Object
describing an OData conceptual schema.</param>
- /// <param name="recognizeDates" type="Boolean" optional="true">Flag
indicating whether datetime literal strings should be converted to JavaScript
Date objects.</param>
- /// <returns type="Object">Top level collection property
object.</param>
-
- var propertyMetadata = {};
- var value = jsonLightReadCollectionPropertyValue(data.value, typeName,
propertyMetadata, baseURI, model, recognizeDates);
- extend(value.__metadata, propertyMetadata);
- return jsonLightReadDataAnnotations(data, value, baseURI);
- };
-
- var jsonLightReadLinksDocument = function (data, baseURI) {
- /// <summary>Converts a JSON light links collection object to its
library representation.</summary>
- /// <param name="data" type="Object">JSON light link object to
convert.</param>
- /// <param name="baseURI" type="String">Base URI for normalizing
relative URIs found in the payload.</param>
- /// <returns type="Object">Links collection object.</param>
-
- var items = data.value;
- if (!isArray(items)) {
- return jsonLightReadLink(data, baseURI);
- }
-
- var results = [];
- var i, len;
- for (i = 0, len = items.length; i < len; i++) {
- results.push(jsonLightReadLink(items[i], baseURI));
- }
-
- var links = { results: results };
- return jsonLightReadDataAnnotations(data, links, baseURI);
- };
-
- var jsonLightReadLink = function (data, baseURI) {
- /// <summary>Converts a JSON light link object to its library
representation.</summary>
- /// <param name="data" type="Object">JSON light link object to
convert.</param>
- /// <param name="baseURI" type="String">Base URI for normalizing
relative URIs found in the payload.</param>
- /// <returns type="Object">Link object.</param>
-
- var link = { uri: normalizeURI(data.url, baseURI) };
-
- link = jsonLightReadDataAnnotations(data, link, baseURI);
- var metadata = link.__metadata || {};
- var metadataProperties = metadata.properties || {};
-
- jsonLightRemoveTypePropertyMetadata(metadataProperties.url);
- renameProperty(metadataProperties, "url", "uri");
-
- return link;
- };
-
- var jsonLightRemoveTypePropertyMetadata = function (propertyMetadata) {
- /// <summary>Removes the type property from a property metadata
object.</summary>
- /// <param name="propertyMetadata" type="Object">Property metadata
object.</param>
-
- if (propertyMetadata) {
- delete propertyMetadata.type;
- }
- };
-
- var jsonLightReadSvcDocument = function (data, baseURI) {
- /// <summary>Converts a JSON light service document object to its
library representation.</summary>
- /// <param name="data" type="Object">JSON light service document
object to convert.</param>
- /// <param name="baseURI" type="String">Base URI for normalizing
relative URIs found in the payload.</param>
- /// <returns type="Object">Link object.</param>
-
- var items = data.value;
- var collections = [];
- var workspace = jsonLightReadDataAnnotations(data, { collections:
collections }, baseURI);
-
- var metadata = workspace.__metadata || {};
- var metadataProperties = metadata.properties || {};
-
- jsonLightRemoveTypePropertyMetadata(metadataProperties.value);
- renameProperty(metadataProperties, "value", "collections");
-
- var i, len;
- for (i = 0, len = items.length; i < len; i++) {
- var item = items[i];
- var collection = { title: item.name, href: normalizeURI(item.url,
baseURI) };
-
- collection = jsonLightReadDataAnnotations(item, collection,
baseURI);
- metadata = collection.__metadata || {};
- metadataProperties = metadata.properties || {};
-
- jsonLightRemoveTypePropertyMetadata(metadataProperties.name);
- jsonLightRemoveTypePropertyMetadata(metadataProperties.url);
-
- renameProperty(metadataProperties, "name", "title");
- renameProperty(metadataProperties, "url", "href");
-
- collections.push(collection);
- }
-
- return { workspaces: [workspace] };
- };
-
- var jsonLightMakePayloadInfo = function (kind, type) {
- /// <summary>Creates an object containing information for the json
light payload.</summary>
- /// <param name="kind" type="String">JSON light payload kind, one of
the PAYLOADTYPE_XXX constant values.</param>
- /// <param name="typeName" type="String">Type name of the JSON light
payload.</param>
- /// <returns type="Object">Object with kind and type fields.</returns>
-
- /// <field name="kind" type="String">Kind of the JSON light payload.
One of the PAYLOADTYPE_XXX constant values.</field>
- /// <field name="type" type="String">Data type of the JSON light
payload.</field>
-
- return { kind: kind, type: type || null };
- };
-
- var jsonLightPayloadInfo = function (data, model, inferFeedAsComplexType) {
- /// <summary>Infers the information describing the JSON light payload
from its metadata annotation, structure, and data model.</summary>
- /// <param name="data" type="Object">Json light response payload
object.</param>
- /// <param name="model" type="Object">Object describing an OData
conceptual schema.</param>
- /// <param name="inferFeedAsComplexType" type="Boolean">True if a JSON
light payload that looks like a feed should be treated as a complex type
property instead.</param>
- /// <remarks>
- /// If the arguments passed to the function don't convey enough
information about the payload to determine without doubt that the payload is a
feed then it
- /// will try to use the payload object structure instead. If the
payload looks like a feed (has value property that is an array or non-primitive
values) then
- /// the function will report its kind as PAYLOADTYPE_FEED unless
the inferFeedAsComplexType flag is set to true. This flag comes from the user
request
- /// and allows the user to control how the library behaves with an
ambigous JSON light payload.
- /// </remarks>
- /// <returns type="Object">
- /// Object with kind and type fields. Null if there is no metadata
annotation or the payload info cannot be obtained..
- /// </returns>
-
- var metadataUri = data[contextUrlAnnotation];
- if (!metadataUri || typeof metadataUri !== "string") {
- return null;
- }
-
- var fragmentStart = metadataUri.lastIndexOf("#");
- if (fragmentStart === -1) {
- return jsonLightMakePayloadInfo(PAYLOADTYPE_SVCDOC);
- }
-
- var elementStart = metadataUri.indexOf("@Element", fragmentStart);
- var fragmentEnd = elementStart - 1;
-
- if (fragmentEnd < 0) {
- fragmentEnd = metadataUri.indexOf("?", fragmentStart);
- if (fragmentEnd === -1) {
- fragmentEnd = metadataUri.length;
- }
- }
-
- var fragment = metadataUri.substring(fragmentStart + 1, fragmentEnd);
- if (fragment.indexOf("/$links/") > 0) {
- return jsonLightMakePayloadInfo(PAYLOADTYPE_LINKS);
- }
-
- var fragmentParts = fragment.split("/");
- if (fragmentParts.length >= 0) {
- var qualifiedName = fragmentParts[0];
- var typeCast = fragmentParts[1];
-
- if (jsonLightIsPrimitiveType(qualifiedName)) {
- return jsonLightMakePayloadInfo(PAYLOADTYPE_PRIMITIVE,
qualifiedName);
- }
-
- if (isCollectionType(qualifiedName)) {
- return jsonLightMakePayloadInfo(PAYLOADTYPE_COLLECTION,
qualifiedName);
- }
-
- var entityType = typeCast;
- var entitySet, functionImport, containerName;
- if (!typeCast) {
- var nsEnd = qualifiedName.lastIndexOf(".");
- var simpleName = qualifiedName.substring(nsEnd + 1);
- var container = (simpleName === qualifiedName) ?
- lookupDefaultEntityContainer(model) :
- lookupEntityContainer(qualifiedName.substring(0, nsEnd),
model);
-
- if (container) {
- entitySet = lookupEntitySet(container.entitySet,
simpleName);
- functionImport = container.functionImport;
- containerName = container.name;
- entityType = !!entitySet ? entitySet.entityType : null;
- }
- }
-
- var info;
- if (elementStart > 0) {
- info = jsonLightMakePayloadInfo(PAYLOADTYPE_OBJECT,
entityType);
- info.entitySet = entitySet;
- info.functionImport = functionImport;
- info.containerName = containerName;
- return info;
- }
-
- if (entityType) {
- info = jsonLightMakePayloadInfo(PAYLOADTYPE_FEED, entityType);
- info.entitySet = entitySet;
- info.functionImport = functionImport;
- info.containerName = containerName;
- return info;
- }
-
- if (isArray(data.value) && !lookupComplexType(qualifiedName,
model)) {
- var item = data.value[0];
- if (!isPrimitive(item)) {
- if (jsonLightIsEntry(item) || !inferFeedAsComplexType) {
- return jsonLightMakePayloadInfo(PAYLOADTYPE_FEED,
null);
- }
- }
- }
-
- return jsonLightMakePayloadInfo(PAYLOADTYPE_OBJECT, qualifiedName);
- }
-
- return null;
- };
-
- var jsonLightReadPayload = function (data, model, recognizeDates,
inferFeedAsComplexType, contentTypeOdata) {
- /// <summary>Converts a JSON light response payload object into its
library's internal representation.</summary>
- /// <param name="data" type="Object">Json light response payload
object.</param>
- /// <param name="model" type="Object">Object describing an OData
conceptual schema.</param>
- /// <param name="recognizeDates" type="Boolean" optional="true">Flag
indicating whether datetime literal strings should be converted to JavaScript
Date objects.</param>
- /// <param name="inferFeedAsComplexType" type="Boolean">True if a JSON
light payload that looks like a feed should be reported as a complex type
property instead.</param>
- /// <param name="contentTypeOdata" type="string">Includes the type of
json ( minimalmetadata, fullmetadata .. etc )</param>
- /// <returns type="Object">Object in the library's
representation.</returns>
-
- if (!isComplex(data)) {
- return data;
- }
-
- contentTypeOdata = contentTypeOdata || "minimal";
- var baseURI = data[contextUrlAnnotation];
- var payloadInfo = jsonLightPayloadInfo(data, model,
inferFeedAsComplexType);
- if (assigned(payloadInfo)) {
- payloadInfo.contentTypeOdata = contentTypeOdata;
- }
- var typeName = null;
- if (payloadInfo) {
- delete data[contextUrlAnnotation];
-
- typeName = payloadInfo.type;
- switch (payloadInfo.kind) {
- case PAYLOADTYPE_FEED:
- return jsonLightReadFeed(data, payloadInfo, baseURI,
model, recognizeDates);
- case PAYLOADTYPE_COLLECTION:
- return jsonLightReadTopCollectionProperty(data, typeName,
baseURI, model, recognizeDates);
- case PAYLOADTYPE_PRIMITIVE:
- return jsonLightReadTopPrimitiveProperty(data, typeName,
baseURI, recognizeDates);
- case PAYLOADTYPE_SVCDOC:
- return jsonLightReadSvcDocument(data, baseURI);
- case PAYLOADTYPE_LINKS:
- return jsonLightReadLinksDocument(data, baseURI);
- }
- }
- return jsonLightReadObject(data, payloadInfo, baseURI, model,
recognizeDates);
- };
-
- var jsonLightSerializableMetadata = ["@odata.type", "@odata.etag",
"@odata.mediaEditLink", "@odata.mediaReadLink", "@odata.mediaContentType",
"@odata.mediaEtag"];
-
- var formatJsonLightRequestPayload = function (data) {
- if (!data) {
- return data;
- }
-
- if (isPrimitive(data)) {
- return data;
- }
-
- if (isArray(data)) {
- var newArrayData = [];
- var i, len;
- for (i = 0, len = data.length; i < len; i++) {
- newArrayData[i] = formatJsonLightRequestPayload(data[i]);
- }
-
- return newArrayData;
- }
-
- var newdata = {};
- for (var property in data) {
- if (isJsonLightSerializableProperty(property)) {
- newdata[property] =
formatJsonLightRequestPayload(data[property]);
- }
- }
-
- return newdata;
- };
-
- var isJsonLightSerializableProperty = function (property) {
- if (!property) {
- return false;
- }
-
- if (property.indexOf("@odata.") == -1) {
- return true;
- }
-
- var i, len;
- for (i = 0, len = jsonLightSerializableMetadata.length; i < len; i++) {
- var name = jsonLightSerializableMetadata[i];
- if (property.indexOf(name) != -1) {
- return true;
- }
- }
-
- return false;
- };
-
- var formatJsonLight = function (obj, context) {
- /// <summary>Converts an object in the library's internal
representation to its json light representation.</summary>
- /// <param name="obj" type="Object">Object the library's internal
representation.</param>
- /// <param name="context" type="Object">Object with the serialization
context.</param>
- /// <returns type="Object">Object in its json light
representation.</returns>
-
- // Regular expression used to test that the uri is for a $links
document.
- var linksUriRE = /\/\$links\//;
- var data = {};
- var metadata = obj.__metadata;
-
- var islinks = context && linksUriRE.test(context.request.requestUri);
- formatJsonLightData(obj, (metadata && metadata.properties), data,
islinks);
- return data;
- };
-
- var formatJsonLightMetadata = function (metadata, data) {
- /// <summary>Formats an object's metadata into the appropriate json
light annotations and saves them to data.</summary>
- /// <param name="obj" type="Object">Object whose metadata is going to
be formatted as annotations.</param>
- /// <param name="data" type="Object">Object on which the annotations
are going to be stored.</param>
-
- if (metadata) {
- var i, len;
- for (i = 0, len = jsonLightSerializableMetadata.length; i < len;
i++) {
- // There is only a subset of metadata values that are
interesting during update requests.
- var name = jsonLightSerializableMetadata[i];
- var qName = odataAnnotationPrefix + (jsonLightNameMap[name] ||
name);
- formatJsonLightAnnotation(qName, null, metadata[name], data);
- }
- }
- };
-
- var formatJsonLightData = function (obj, pMetadata, data, isLinks) {
- /// <summary>Formats an object's data into the appropriate json light
values and saves them to data.</summary>
- /// <param name="obj" type="Object">Object whose data is going to be
formatted.</param>
- /// <param name="pMetadata" type="Object">Object that contains
metadata for the properties that are being formatted.</param>
- /// <param name="data" type="Object">Object on which the formatted
values are going to be stored.</param>
- /// <param name="isLinks" type="Boolean">True if a links document is
being formatted. False otherwise.</param>
-
- for (var key in obj) {
- var value = obj[key];
- if (key === "__metadata") {
- // key is the object metadata.
- formatJsonLightMetadata(value, data);
- } else if (key.indexOf(".") === -1) {
- // key is an regular property or array element.
- if (isLinks && key === "uri") {
- formatJsonLightEntityLink(value, data);
- } else {
- formatJsonLightProperty(key, value, pMetadata, data,
isLinks);
- }
- } else {
- data[key] = value;
- }
- }
- };
-
- var formatJsonLightProperty = function (name, value, pMetadata, data) {
- /// <summary>Formats an object's value identified by name to its json
light representation and saves it to data.</summary>
- /// <param name="name" type="String">Property name.</param>
- /// <param name="value">Property value.</param>
- /// <param name="pMetadata" type="Object">Object that contains
metadata for the property that is being formatted.</param>
- /// <param name="data" type="Object">Object on which the formatted
value is going to be stored.</param>
-
- // Get property type from property metadata
- var propertyMetadata = pMetadata && pMetadata[name] || { properties:
undefined, type: undefined };
- var typeName = dataItemTypeName(value, propertyMetadata);
-
- if (isPrimitive(value) || !value) {
- // It is a primitive value then.
- formatJsonLightAnnotation(typeAnnotation, name, typeName, data);
- data[name] = value;
- return;
- }
-
- if (isFeed(value, typeName) || isEntry(value)) {
- formatJsonLightInlineProperty(name, value, data);
- return;
- }
-
- if (!typeName && isDeferred(value)) {
- // It is really a deferred property.
- formatJsonLightDeferredProperty(name, value, data);
- return;
- }
-
- if (isCollection(value, typeName)) {
- // The thing is a collection, format it as one.
- if (getCollectionType(typeName)) {
- formatJsonLightAnnotation(typeAnnotation, name, typeName,
data);
- }
- formatJsonLightCollectionProperty(name, value, data);
- return;
- }
-
- djsassert(isComplex(value), "formatJsonLightProperty - Value is not a
complex type value");
-
- // Format the complex property value in a new object in data[name].
- data[name] = {};
- formatJsonLightAnnotation(typeAnnotation, null, typeName, data[name]);
- formatJsonLightData(value, propertyMetadata.properties, data[name]);
- };
-
- var formatJsonLightEntityLink = function (value, data) {
- /// <summary>Formats an entity link in a $links document and saves it
into data.</summary>
- /// <param name="value" type="String">Entity link value.</summary>
- /// <param name="data" type="Object">Object on which the formatted
value is going to be stored.</param>
- data.url = value;
- };
-
- var formatJsonLightDeferredProperty = function (name, value, data) {
- /// <summary>Formats the object value's identified by name as an
odata.navigalinkurl annotation and saves it to data.</summary>
- /// <param name="name" type="String">Name of the deferred property to
be formatted.</param>
- /// <param name="value" type="Object">Deferred property value to be
formatted.</param>
- /// <param name="data" type="Object">Object on which the formatted
value is going to be stored.</param>
-
- formatJsonLightAnnotation(navUrlAnnotation, name,
value.__deferred.uri, data);
- };
-
- var formatJsonLightCollectionProperty = function (name, value, data) {
- /// <summary>Formats a collection property in obj identified by name
as a json light collection property and saves it to data.</summary>
- /// <param name="name" type="String">Name of the collection property
to be formatted.</param>
- /// <param name="value" type="Object">Collection property value to be
formatted.</param>
- /// <param name="data" type="Object">Object on which the formatted
value is going to be stored.</param>
-
- data[name] = [];
- var items = isArray(value) ? value : value.results;
- formatJsonLightData(items, null, data[name]);
- };
-
- var formatJsonLightInlineProperty = function (name, value, data) {
- /// <summary>Formats an inline feed or entry property in obj
identified by name as a json light value and saves it to data.</summary>
- /// <param name="name" type="String">Name of the inline feed or entry
property to be formatted.</param>
- /// <param name="value" type="Object or Array">Value of the inline
feed or entry property.</param>
- /// <param name="data" type="Object">Object on which the formatted
value is going to be stored.</param>
-
- if (isFeed(value)) {
- data[name] = [];
- // Format each of the inline feed entries
- var entries = isArray(value) ? value : value.results;
- var i, len;
- for (i = 0, len = entries.length; i < len; i++) {
- formatJsonLightInlineEntry(name, entries[i], true, data);
- }
- return;
- }
- formatJsonLightInlineEntry(name, value, false, data);
- };
-
- var formatJsonLightInlineEntry = function (name, value, inFeed, data) {
- /// <summary>Formats an inline entry value in the property identified
by name as a json light value and saves it to data.</summary>
- /// <param name="name" type="String">Name of the inline feed or entry
property that owns the entry formatted.</param>
- /// <param name="value" type="Object">Inline entry value to be
formatted.</param>
- /// <param name="inFeed" type="Boolean">True if the entry is in an
inline feed; false otherwise.
- /// <param name="data" type="Object">Object on which the formatted
value is going to be stored.</param>
-
- // This might be a bind instead of a deep insert.
- var uri = value.__metadata && value.__metadata.uri;
- if (uri) {
- formatJsonLightBinding(name, uri, inFeed, data);
- return;
- }
-
- var entry = formatJsonLight(value);
- if (inFeed) {
- data[name].push(entry);
- return;
- }
- data[name] = entry;
- };
-
- var formatJsonLightBinding = function (name, uri, inFeed, data) {
- /// <summary>Formats an entry binding in the inline property in obj
identified by name as an odata.bind annotation and saves it to data.</summary>
- /// <param name="name" type="String">Name of the inline property that
has the binding to be formated.</param>
- /// <param name="uri" type="String">Uri to the bound entry.</param>
- /// <param name="inFeed" type="Boolean">True if the binding is in an
inline feed; false otherwise.
- /// <param name="data" type="Object">Object on which the formatted
value is going to be stored.</param>
-
- var bindingName = name + bindAnnotation;
- if (inFeed) {
- // The binding is inside an inline feed, so merge it with whatever
other bindings already exist in data.
- data[bindingName] = data[bindingName] || [];
- data[bindingName].push(uri);
- return;
- }
- // The binding is on an inline entry; it can be safely overwritten.
- data[bindingName] = uri;
- };
-
- var formatJsonLightAnnotation = function (qName, target, value, data) {
- /// <summary>Formats a value as a json light annotation and stores it
in data</summary>
- /// <param name="qName" type="String">Qualified name of the
annotation.</param>
- /// <param name="target" type="String">Name of the property that the
metadata value targets.</param>
- /// <param name="value">Annotation value.</param>
- /// <param name="data" type="Object">Object on which the annotation is
going to be stored.</param>
-
- if (value !== undefined) {
- if (target) {
- data[target + "@" + qName] = value;
- }
- else {
- data[qName] = value;
- }
- }
- };
-
- // DATAJS INTERNAL START
- odata.jsonLightReadPayload = jsonLightReadPayload;
- odata.formatJsonLight = formatJsonLight;
- odata.formatJsonLightRequestPayload = formatJsonLightRequestPayload;
- // DATAJS INTERNAL END
-
- // CONTENT END
-})(this);
-
-
-