[OLINGO-324] merge metadata and payload
diff --git a/datajs/demo/tester.html b/datajs/demo/tester.html
index 43bca29..0b0caa0 100644
--- a/datajs/demo/tester.html
+++ b/datajs/demo/tester.html
@@ -42,12 +42,13 @@
<button id="btnJSONwithMetaData">JSON with MetaData</button><br/>
<div id='resultsArea' data-type="json">
</div>
- <script type='text/html' id='template'>
- {{#items}}
- <p><a href="{{id}}">{{name}}</a></p>
- {{/items}}
- </script>
<script>
+ //var x = eval("(function (w, undefined) {alert('A '+JSON.stringify(w.screen));})(this);");
+ //(function () {
+ // var x = eval("(function (w, undefined) {alert('B '+JSON.stringify(w.screen));})(this);");
+ //})();
+
+
function show(data) {
$('#resultsArea').empty();
var code = $('<code data-type="json"></code>').text(JSON.stringify(data))
@@ -78,34 +79,34 @@
requestUri: "http://localhost:4002/tests/endpoints/FoodStoreDataServiceV4.svc/$metadata", //"http://localhost:6630/PrimitiveKeys.svc/$metadata",
data: null,
};
- OData.read(metadataRequest, metaDatasuccess, errorFunc,OData.metadataHandler);
+ datajs.V4.oData.read(metadataRequest, metaDatasuccess, errorFunc,datajs.V4.oData.metadataHandler);
};
$('#startXML').on("click", function(){
//var requestUri = 'http://localhost:4002/tests/endpoints/FoodStoreDataServiceV4.svc/Foods';
var requestUri ='http://localhost:4003/sap/bc/ds/odata/v4/ESMixPrimCollComp?$format=xml';
- OData.read(requestUri, success, errorFunc);
+ datajs.V4.oData.read(requestUri, success, errorFunc);
});
$('#btnJSON_none').on("click", function(){
var requestUri = {
requestUri : 'http://localhost:4002/tests/endpoints/FoodStoreDataServiceV4.svc/Foods',
headers : { Accept : 'application/json;odata.metadata=none' }
};
- OData.read(requestUri, success, errorFunc);
+ datajs.V4.oData.read(requestUri, success, errorFunc);
});
$('#btnJSON_minimal').on("click", function(){
var requestUri = {
requestUri : 'http://localhost:4002/tests/endpoints/FoodStoreDataServiceV4.svc/Foods',
headers : { Accept : 'application/json;odata.metadata=minimal' }
};
- OData.read(requestUri, success, errorFunc);
+ datajs.V4.oData.read(requestUri, success, errorFunc);
});
$('#btnJSON_full').on("click", function(){
var requestUri = {
requestUri : 'http://localhost:4002/tests/endpoints/FoodStoreDataServiceV4.svc/Foods',
headers : { Accept : 'application/json;odata.metadata=full' }
};
- OData.read(requestUri, success, errorFunc);
+ datajs.V4.oData.read(requestUri, success, errorFunc);
});
$('#btnJSON_full_to_all').on("click", function(){
@@ -115,7 +116,7 @@
extendMetadataToLevel : 'all' ,
recognizeDates : false
};
- OData.read(requestUri, success, errorFunc);
+ datajs.V4.oData.read(requestUri, success, errorFunc);
});
$('#btnJSON_full_to_all_date_conversion').on("click", function(){
var requestUri = {
@@ -124,7 +125,7 @@
extendMetadataToLevel : 'all' ,
recognizeDates : true
};
- OData.read(requestUri, success, errorFunc);
+ datajs.V4.oData.read(requestUri, success, errorFunc);
});
$('#btnJSON_full_date_conversion').on("click", function(){
var requestUri = {
@@ -132,7 +133,7 @@
headers : { Accept : 'application/json;odata.metadata=full' },
recognizeDates : true
};
- OData.read(requestUri, success, errorFunc);
+ datajs.V4.oData.read(requestUri, success, errorFunc);
});
$('#btnMetaData').on("click", function(){
@@ -150,7 +151,7 @@
data: null,
};
- OData.read(metadataRequest, success, errorFunc,OData.metadataHandler);
+ datajs.V4.oData.read(metadataRequest, success, errorFunc,datajs.V4.oData.metadataHandler);
});
@@ -163,7 +164,7 @@
extendMetadataToLevel : 'all' ,
recognizeDates : false
};
- OData.read(requestUri, success, errorFunc, null, null, metadata);
+ datajs.V4.oData.read(requestUri, success, errorFunc, null, null, metadata);
}
getMetaData(metaDatasuccess);
});
@@ -176,7 +177,7 @@
extendMetadataToLevel : 'full' ,
recognizeDates : false
};
- OData.read(requestUri, success, errorFunc, null, null, metadata);
+ datajs.V4.oData.read(requestUri, success, errorFunc, null, null, metadata);
}
getMetaData(metaDatasuccess);
});
@@ -198,11 +199,11 @@
var metaDatasuccess = function(metadata){
var requestUri = 'http://localhost:4002/tests/endpoints/FoodStoreDataServiceV4.svc/Foods';
- OData.read(requestUri, success, errorFunc, null, null, metadata);
+ datajs.V4.oData.read(requestUri, success, errorFunc, null, null, metadata);
}
- OData.read(metadataRequest, metaDatasuccess, errorFunc,OData.metadataHandler);
+ datajs.V4.oData.read(metadataRequest, metaDatasuccess, errorFunc,datajs.V4.oData.metadataHandler);
});
</script>
diff --git a/datajs/demo/testerV2.html b/datajs/demo/testerV2.html
index a480f8f..b9bf1c8 100644
--- a/datajs/demo/testerV2.html
+++ b/datajs/demo/testerV2.html
@@ -28,20 +28,17 @@
</style>
</head>
<body>
- <button id="startXML">startXML</button><br/>
- <button id="startJSON">startJSON</button><br/>
+ <button id="btnMetaData">MetaData</button><br/>
+ <button id="btnJSON_minimal">pure JSON</button><br/>
+
<div id='resultsArea'>
</div>
- <script type='text/html' id='template'>
- {{#items}}
- <p><a href="{{id}}">{{name}}</a></p>
- {{/items}}
- </script>
<script>
function show(data) {
$('#resultsArea').empty();
- $('#resultsArea').text(JSON.stringify(data))
+ var code = $('<code data-type="json"></code>').text(JSON.stringify(data))
+ $('#resultsArea').append(code);
$('code[data-type]').prettify();
}
function success(data) {
@@ -53,13 +50,19 @@
$("#resultsArea").text(JSON.stringify(err));
}
+
+ $('#btnMetaData').on("click", function(){
+ var metadata;
+ OData.read("http://localhost:4003/sap/bc/ds/odata/v2/$metadata",success, errorFunc, OData.metadataHandler);
+ });
+
$('#startXML').on("click", function(){
//var requestUri = 'http://localhost:4002/tests/endpoints/FoodStoreDataServiceV4.svc/Foods';
var requestUri ='http://localhost:4003/sap/bc/odata/Employees';
OData.read(requestUri, success, errorFunc);
});
- $('#startJSON').on("click", function(){
- //var requestUri = 'http://localhost:4002/tests/endpoints/FoodStoreDataServiceV4.svc/Foods';
+
+ $('#btnJSON_minimal').on("click", function(){
var requestUri ='http://localhost:4003/sap/bc/odata/Employees?$format=json';
OData.read(requestUri, success, errorFunc);
});
diff --git a/datajs/src/index.js b/datajs/src/index.js
index c89a2b6..82fc374 100644
--- a/datajs/src/index.js
+++ b/datajs/src/index.js
@@ -17,11 +17,15 @@
* under the License.
*/
-window.datajs = require('./lib/datajs.js');
-window.OData = require('./lib/odata.js');
+if ( window.datajs===undefined) {
+ window.datajs = {};
+}
-window.datajs.store = require('./lib/store.js');
-window.datajs.cache = require('./lib/cache.js');
+window.datajs.V4 = require('./lib/datajs.js');
+window.datajs.V4.oData = require('./lib/odata.js');
+
+window.datajs.V4.store = require('./lib/store.js');
+window.datajs.V4.cache = require('./lib/cache.js');
function extend(target) {
var sources = [].slice.call(arguments, 1);
diff --git a/datajs/src/lib/odata.js b/datajs/src/lib/odata.js
index 297a339..55f4a4e 100644
--- a/datajs/src/lib/odata.js
+++ b/datajs/src/lib/odata.js
@@ -18,19 +18,17 @@
// odata.js
// Imports
-exports.utils = odataUtils = require('./odata/utils.js');
-exports.handler = odataHandler = require('./odata/handler.js');
-exports.metadata = odataMetadata = require('./odata/metadata.js');
-exports.net = odataNet = require('./odata/net.js');
-//exports.net = odataNet = require('./odata/net-nodejs.js');//testing only
-exports.gml = require('./odata/gml.js');
-exports.jsonLight = require('./odata/json-light.js');
-exports.json = odataJson = require('./odata/json.js');
-exports.atom = odataAtom = require('./odata/atom.js');
-exports.xml = odataXml = require('./odata/xml.js');
-exports.batch = require('./odata/batch.js');
-
-exports.metadataHandler = odataMetadata.metadataHandler;
+var odataUtils = exports.utils = require('./odata/utils.js');
+var odataHandler = exports.handler = require('./odata/handler.js');
+var odataMetadata = exports.metadata = require('./odata/metadata.js');
+var odataNet = exports.net = require('./odata/net.js');
+ exports.gml = require('./odata/gml.js');
+var odataJson = exports.json = require('./odata/json.js');
+var odataAtom = exports.atom = require('./odata/atom.js');
+var odataXml = exports.xml = require('./odata/xml.js');
+ exports.batch = require('./odata/batch.js');
+
+exports.metadataHandler = odataMetadata.metadataHandler;
diff --git a/datajs/src/lib/odata/json-light.js b/datajs/src/lib/odata/json-light.js
index eddd58c..aefa27f 100644
--- a/datajs/src/lib/odata/json-light.js
+++ b/datajs/src/lib/odata/json-light.js
@@ -32,6 +32,7 @@
var getURIInfo = utils.getURIInfo;
var isArray = utils.isArray;
var isDate = utils.isDate;
+var isObject = utils.isObject;
var normalizeURI = utils.normalizeURI;
var renameProperty = utils.renameProperty;
var undefinedDefault = utils.undefinedDefault;
@@ -72,21 +73,15 @@
var PAYLOADTYPE_FEED = "f";
var PAYLOADTYPE_ENTRY = "e";
var PAYLOADTYPE_PROPERTY = "p";
+var PAYLOADTYPE_COLLECTION = "c";
+var PAYLOADTYPE_ENUMERATION_PROPERTY = "enum";
+var PAYLOADTYPE_SVCDOC = "s";
var PAYLOADTYPE_ENTITY_REF_LINK = "erl";
var PAYLOADTYPE_ENTITY_REF_LINKS = "erls";
+
var PAYLOADTYPE_VALUE = "v";
-var PAYLOADTYPE_BINARY_VALUE = "bv";
-var PAYLOADTYPE_COLLECTION = "c";
-var PAYLOADTYPE_SVCDOC = "s";
-var PAYLOADTYPE_METADOC = "m";
-var PAYLOADTYPE_ERROR = "err";
-var PAYLOADTYPE_BATCH = "b";
-var PAYLOADTYPE_PARAMETER = "para";
-var PAYLOADTYPE_IND_PROPERTY = "ip";
+
var PAYLOADTYPE_DELTA = "d";
-var PAYLOADTYPE_ASYNC = "a";
-
-
var DELTATYPE_FEED = "f";
var DELTATYPE_DELETED_ENTRY = "de";
var DELTATYPE_LINK = "l";
@@ -197,6 +192,7 @@
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>
@@ -213,6 +209,7 @@
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>
@@ -530,6 +527,103 @@
return null;
};
+var jsonLightReadComplexObjectNew = function (data, property, baseURI, model, demandedFormat, recognizeDates) {
+ var type = property.type;
+ if (isCollectionType(property.type)) {
+ type =property.type.substring(11,property.type.length-1);
+ }
+
+ data['@odata.type'] = '#'+type;
+
+
+
+ var propertyType = lookupComplexType(type, model);
+ if (propertyType === null) {
+ return; //TODO check what to do if the type is not known e.g. type #GeometryCollection
+ }
+
+ var curType = propertyType;
+
+
+ for (var name in data) {
+ if (name.indexOf("@") === -1) {
+ var propertyValue = data[name];
+ var property = lookupProperty(curType.property,name); //TODO SK add check for parent type
+
+ while (( property === null) && (curType.baseType !== undefined)) {
+ curType = lookupEntityType(curType.baseType, model);
+ property = lookupProperty(curType.property,name);
+ }
+ if (demandedFormat === 3) {
+ if ( isArray(propertyValue)) {
+ data[name+'@odata.type'] = '#' + property.type;
+ for ( var i = 0; i < propertyValue.length; i++) {
+ jsonLightReadComplexObjectNew(propertyValue[0], property,baseURI,model,demandedFormat, recognizeDates);
+ }
+ } else if (isObject(propertyValue) && (propertyValue!= null)) {
+ jsonLightReadComplexObjectNew(propertyValue, property,baseURI,model,demandedFormat, recognizeDates);
+ } else {
+ data[name+'@odata.type'] = '#' + property.type;
+ }
+
+ } else {
+
+ }
+ }
+ }
+}
+
+
+var jsonLightReadObjectNew = function (data, objectInfo, baseURI, model, demandedFormat, recognizeDates) {
+ //var obj = {};
+
+ data['@odata.type'] = '#'+objectInfo.typeName;
+
+ var keyType = objectInfo.type;
+ while (( keyType.key === undefined) && (keyType.baseType !== undefined)) {
+ keyType = lookupEntityType(keyType.baseType, model);
+ }
+
+ var lastIdSegment = objectInfo.name + jsonLightGetEntryKey(data, keyType);
+ data['@odata.id'] = baseURI.substring(0, baseURI.lastIndexOf("$metadata")) + lastIdSegment;
+ data['@odata.editLink'] = lastIdSegment;
+
+ var serviceURI = baseURI.substring(0, baseURI.lastIndexOf("$metadata"));
+ //jsonLightComputeUrisIfMissing(data, entryInfo, actualType, serviceURI, dataModel, baseTypeModel);
+
+
+
+ for (var name in data) {
+ if (name.indexOf("@") === -1) {
+ var curType = objectInfo.type;
+ var propertyValue = data[name];
+ var property = lookupProperty(curType.property,name); //TODO SK add check for parent type
+
+ while (( property === null) && (curType.baseType !== undefined)) {
+ curType = lookupEntityType(curType.baseType, model);
+ property = lookupProperty(curType.property,name);
+ }
+ if (demandedFormat === 3) {
+ if ( isArray(propertyValue)) {
+ data[name+'@odata.type'] = '#' + property.type;
+ for ( var i = 0; i < propertyValue.length; i++) {
+ jsonLightReadComplexObjectNew(propertyValue[0], property,baseURI,model,demandedFormat, recognizeDates);
+ }
+ } else if (isObject(propertyValue) && (propertyValue!= null)) {
+ jsonLightReadComplexObjectNew(propertyValue, property,baseURI,model,demandedFormat, recognizeDates);
+ } else {
+ data[name+'@odata.type'] = '#' + property.type;
+ }
+
+ } else {
+
+ }
+ }
+ }
+
+ return data;
+};
+
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>
@@ -673,6 +767,34 @@
}
};
+var jsonLightReadFeedNew = function (data, feedInfo, baseURI, model, demandedFormat,recognizeDates) {
+ var entries = [];
+ var items = data.value;
+ for (i = 0, len = items.length; i < len; i++) {
+ //TODO SK check if items[i] has @odata.type and use this type instead of feedinfo
+
+ if ( items[i]['@odata.type'] !== undefined) {
+ var typeName = items[i]['@odata.type'].substring(1);
+ var type = lookupEntityType( typeName, model);
+ var entryInfo = {
+ contentTypeOdata : feedInfo.contentTypeOdata,
+ detectedPayloadKind : feedInfo.detectedPayloadKind,
+ name : feedInfo.name,
+ type : type,
+ typeName : typeName
+ };
+
+ entry = jsonLightReadObjectNew(items[i], entryInfo, baseURI, model, demandedFormat,recognizeDates);
+ } else {
+ entry = jsonLightReadObjectNew(items[i], feedInfo, baseURI, model, demandedFormat,recognizeDates);
+ }
+
+ entries.push(entry);
+ }
+ data.value = entries;
+ return data;
+};
+
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>
@@ -712,7 +834,7 @@
/// <returns type="string">Entry instance key.</returns>
var entityInstanceKey;
- var entityKeys = entityModel.key.propertyRef;
+ var entityKeys = entityModel.key[0].propertyRef;
var type;
entityInstanceKey = "(";
if (entityKeys.length == 1) {
@@ -1040,277 +1162,10 @@
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 };
-};
-
-/// <summary>Creates an object containing information for the context</summary>
-/// ...
-/// <returns type="Object">Object with type information
-/// attribute detectedPayloadKind(optional): see constants starting with PAYLOADTYPE_
-/// attribute deltaKind(optional): deltainformation, one of the following valus DELTATYPE_FEED | DELTATYPE_DELETED_ENTRY | DELTATYPE_LINK | DELTATYPE_DELETED_LINK
-/// attribute typeName(optional): name of the type
-/// attribute type(optional): object containing type information for entity- and complex-types ( null if a typeName is a primitive)
-/// </returns>
-var parseContextUriFragment = function( fragment, model ) {
- var ret = {};
-
-
- if (fragment.indexOf('/') === -1 ) {
- if (fragment.length === 0) {
- // Capter 10.1
- ret.detectedPayloadKind = PAYLOADTYPE_SVCDOC;
- return ret;
- } else if (fragment === 'Edm.Null') {
- // Capter 10.15
- ret.detectedPayloadKind = PAYLOADTYPE_VALUE;
- ret.isNullProperty = true;
- return ret;
- } else if (fragment === 'Collection($ref)') {
- // Capter 10.11
- ret.detectedPayloadKind = PAYLOADTYPE_ENTITY_REF_LINKS;
- return ret;
- } else if (fragment === '$ref') {
- // Capter 10.12
- ret.detectedPayloadKind = PAYLOADTYPE_ENTITY_REF_LINK;
- return ret;
- } else {
- //TODO check for navigation resource
- }
- }
-
- ret.type = undefined;
- ret.typeName = undefined;
-
- var fragmentParts = fragment.split("/");
-
- for(var i = 0; i < fragmentParts.length; ++i) {
- var fragment = fragmentParts[i];
- if (ret.typeName === undefined) {
- //preparation
- if ( fragment.indexOf('(') !== -1 ) {
- //remove the query function, cut fragment to matching '('
- var index = fragment.length - 2 ;
- for ( var rCount = 1; rCount > 0 && index > 0; --index) {
- if ( fragment.charAt(index)=='(') {
- rCount --;
- } else if ( fragment.charAt(index)==')') {
- rCount ++;
- }
- }
-
- if (index === 0) {
- //TODO throw error
- }
-
- //remove the projected entity from the fragment; TODO decide if we want to store the projected entity
- var inPharenthesis = fragment.substring(index+2,fragment.length - 1);
- fragment = fragment.substring(0,index+1);
-
- if (utils.startsWith(fragment, 'Collection')) {
- ret.detectedPayloadKind = PAYLOADTYPE_COLLECTION;
- // Capter 10.14
- ret.typeName = inPharenthesis;
-
- var type = lookupEntityType(ret.typeName, model);
- if ( type !== null) {
- ret.type = type;
- continue;
- }
- type = lookupComplexType(ret.typeName, model);
- if ( type !== null) {
- ret.type = type;
- continue;
- }
-
- ret.type = null;//in case of #Collection(Edm.String) only lastTypeName is filled
- continue;
- } else {
- // projection: Capter 10.7, 10.8 and 10.9
- ret.projection = inPharenthesis;
- }
- }
-
- var container = lookupDefaultEntityContainer(model);
-
- //check for entity
- var entitySet = lookupEntitySet(container.entitySet, fragment);
- if ( entitySet !== null) {
- ret.typeName = entitySet.entityType;
- ret.type = lookupEntityType( ret.typeName, model);
- ret.detectedPayloadKind = PAYLOADTYPE_FEED;
- // Capter 10.2
- continue;
- }
-
- //check for singleton
- var singleton = lookupSingleton(container.singleton, fragment);
- if ( singleton !== null) {
- ret.typeName = singleton.entityType;
- ret.type = lookupEntityType( ret.typeName, model);
- ret.detectedPayloadKind = PAYLOADTYPE_ENTRY;
- // Capter 10.4
- continue;
- }
-
- if (jsonLightIsPrimitiveType(fragment)) {
- ret.typeName = fragment;
- ret.type = null;
- ret.detectedPayloadKind = PAYLOADTYPE_VALUE;
- continue;
- }
-
- //TODO throw ERROR
- } else {
- //check for $entity
- if (utils.endsWith(fragment, '$entity') && (ret.detectedPayloadKind === PAYLOADTYPE_FEED)) {
- ret.detectedPayloadKind = PAYLOADTYPE_ENTRY;
- // Capter 10.3 and 10.6
- continue;
- }
-
- //check for derived types
- if (fragment.indexOf('.') !== -1) {
- // Capter 10.6
- ret.typeName = fragment;
- var type = lookupEntityType(ret.typeName, model);
- if ( type !== null) {
- ret.type = type;
- continue;
- }
- type = lookupComplexType(ret.typeName, model);
- if ( type !== null) {
- ret.type = type;
- continue;
- }
-
- //TODO throw ERROR invalid type
- }
-
- //check for property value
- if ( ret.detectedPayloadKind === PAYLOADTYPE_FEED || ret.detectedPayloadKind === PAYLOADTYPE_ENTRY) {
- var property = lookupProperty(ret.type.property, fragment);
- if (property !== null) {
- ret.typeName = property.type;
- ret.type = lookupComplexType(ret.typeName, model);
- ret.detectedPayloadKind = PAYLOADTYPE_PROPERTY;
- // Capter 10.15
- }
- continue;
- }
-
- if (fragment === '$delta') {
- ret.deltaKind = DELTATYPE_FEED;
- continue;
- } else if (utils.endsWith(fragment, '/$deletedEntity')) {
- ret.deltaKind = DELTATYPE_DELETED_ENTRY;
- continue;
- } else if (utils.endsWith(fragment, '/$link')) {
- ret.deltaKind = DELTATYPE_LINK;
- continue;
- } else if (utils.endsWith(fragment, '/$deletedLink')) {
- ret.deltaKind = DELTATYPE_DELETED_LINK;
- continue;
- }
- //TODO throw ERROr
- }
- }
- return ret;
-};
-
-var jsonLightPayloadInfo = function (data, model) {
- /// <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>
- /// <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 ret = parseContextUriFragment(fragment,model);
-
- return ret;
-};
-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"];
@@ -1583,8 +1438,8 @@
};
// DATAJS INTERNAL START
-exports.jsonLightPayloadInfo = jsonLightPayloadInfo;
-exports.jsonLightReadPayload = jsonLightReadPayload;
+//exports.jsonLightPayloadInfo = jsonLightPayloadInfo;
+//exports.jsonLightReadPayload = jsonLightReadPayload;
exports.formatJsonLight = formatJsonLight;
exports.formatJsonLightRequestPayload = formatJsonLightRequestPayload;
// DATAJS INTERNAL END
diff --git a/datajs/src/lib/odata/json.js b/datajs/src/lib/odata/json.js
index f5293bf..087f4cf 100644
--- a/datajs/src/lib/odata/json.js
+++ b/datajs/src/lib/odata/json.js
@@ -25,18 +25,21 @@
var utils = require('./../datajs.js').utils;
var oDataUtils = require('./utils.js');
var oDataHandler = require('./handler.js');
-var oJsonLight = require('./json-light.js');
+var odataNs = "odata";
+var odataAnnotationPrefix = odataNs + ".";
+var contextUrlAnnotation = "@" + odataAnnotationPrefix + "context";
+var assigned = utils.assigned;
var defined = utils.defined;
var extend = utils.extend;
var isArray = utils.isArray;
var isDate = utils.isDate;
+var isObject = utils.isObject;
var normalizeURI = utils.normalizeURI;
var parseInt10 = utils.parseInt10;
var contentType = oDataUtils.contentType;
-var jsonLightReadPayload = oJsonLight.jsonLightReadPayload;
var formatDateTimeOffset = oDataUtils.formatDateTimeOffset;
var formatDuration = oDataUtils.formatDuration;
var formatJsonLight = oDataUtils.formatJsonLight;
@@ -44,9 +47,13 @@
var getCanonicalTimezone = oDataUtils.getCanonicalTimezone;
var handler = oDataUtils.handler;
var isComplex = oDataUtils.isComplex;
+var isCollectionType = oDataUtils.isCollectionType;
var lookupComplexType = oDataUtils.lookupComplexType;
var lookupEntityType = oDataUtils.lookupEntityType;
var lookupSingleton = oDataUtils.lookupSingleton;
+var lookupEntitySet = oDataUtils.lookupEntitySet;
+var lookupDefaultEntityContainer = oDataUtils.lookupDefaultEntityContainer;
+var lookupProperty = oDataUtils.lookupProperty;
var MAX_DATA_SERVICE_VERSION = oDataUtils.MAX_DATA_SERVICE_VERSION;
var maxVersion = oDataUtils.maxVersion;
var parseDateTime = oDataUtils.parseDateTime;
@@ -54,13 +61,29 @@
var parseTimezone = oDataUtils.parseTimezone;
var payloadTypeOf = oDataUtils.payloadTypeOf;
var traverse = oDataUtils.traverse;
-var formatJsonLightRequestPayload = oJsonLight.formatJsonLightRequestPayload;
// CONTENT START
+var PAYLOADTYPE_FEED = "f";
+var PAYLOADTYPE_ENTRY = "e";
+var PAYLOADTYPE_PROPERTY = "p";
+var PAYLOADTYPE_COLLECTION = "c";
+var PAYLOADTYPE_ENUMERATION_PROPERTY = "enum";
+var PAYLOADTYPE_SVCDOC = "s";
+var PAYLOADTYPE_ENTITY_REF_LINK = "erl";
+var PAYLOADTYPE_ENTITY_REF_LINKS = "erls";
+
+var PAYLOADTYPE_VALUE = "v";
+
+var PAYLOADTYPE_DELTA = "d";
+var DELTATYPE_FEED = "f";
+var DELTATYPE_DELETED_ENTRY = "de";
+var DELTATYPE_LINK = "l";
+var DELTATYPE_DELETED_LINK = "dl";
+
var jsonMediaType = "application/json";
var jsonContentType = oDataHandler.contentType(jsonMediaType);
-
+/*
var jsonReadAdvertisedActionsOrFunctions = function (value) {
/// <summary>Reads and object containing action or function metadata and maps them into a single array of objects.</summary>
/// <param name="value" type="Object">Object containing action or function metadata.</param>
@@ -74,8 +97,9 @@
}
}
return result;
-};
+};*/
+/*
var jsonApplyMetadata = function (value, metadata, dateParser, recognizeDates) {
/// <summary>Applies metadata coming from both the payload and the metadata object to the value.</summary>
/// <param name="value" type="Object">Data on which the metada is going to be applied.</param>
@@ -136,8 +160,8 @@
}
}
return value;
-};
-
+};*/
+/*
var isJsonLight = function (contentType) {
/// <summary>Tests where the content type indicates a json light payload.</summary>
/// <param name="contentType">Object with media type and properties dictionary.</param>
@@ -148,8 +172,8 @@
return odata === "none" || odata === "minimal" || odata === "full";
}
return false;
-};
-
+};*/
+/*
var normalizeServiceDocument = function (data, baseURI) {
/// <summary>Normalizes a JSON service document to look like an ATOM service document.</summary>
/// <param name="data" type="Object">Object representation of service documents as deserialized.</param>
@@ -169,7 +193,7 @@
}
return { workspaces: [workspace] };
-};
+};*/
// The regular expression corresponds to something like this:
// /Date(123+60)/
@@ -268,8 +292,6 @@
}
demandedFormat = (demandedFormat === undefined) ? 1 : demandedFormat;
- //return jsonLightReadPayload(json, model, recognizeDates, inferJsonLightFeedAsObject, context.contentType.properties['odata.metadata']);
-
if ( payloadFormat >= demandedFormat) {
//there is no need to add additional metadata
if (recognizeDates) {
@@ -294,7 +316,7 @@
if (!utils.isArray(model)) { // array was default for model in datajsV3 3.0
//TODO use metadata in context to determine which properties need to be converted
// and extend the metadata
- return extendMetadataFromContext(json,context,model,recognizeDates);
+ return extendMetadataFromContext(json,context,model,demandedFormat, recognizeDates);
} else {
//error metadata in context required, TODO: throw a to be defined exception
}
@@ -303,19 +325,12 @@
return json;
}
}
-
-
};
-var extendMetadataFromContext = function(json,context, model,recognizeDates) {
- return jsonLightReadPayload(json, model, recognizeDates, false, context.contentType.properties['odata.metadata']);
+var extendMetadataFromContext = function(json,context, model,demandedFormat,recognizeDates) {
+ return jsonLightReadPayload(json, model, demandedFormat,recognizeDates, false, context.contentType.properties['odata.metadata']);
};
-var convertPrimitivetypesGeneric = function(data) {
-
-};
-
-
var convertPrimitivetypesOnMetadataFull = function(data) {
/// <summary>Converts some primitive data types in payload</summary>
/// <param name="data">Date which will be extendet</param>
@@ -419,7 +434,7 @@
-
+/*
var jsonToString = function (data) {
/// <summary>Converts the data into a JSON string.</summary>
/// <param name="data">Data to serialize.</param>
@@ -440,7 +455,7 @@
Date.prototype.toJSON = dateToJSON;
}
return result;
-};
+};*/
var jsonSerializer = function (handler, data, context) {
/// <summary>Serializes the data by returning its string representation.</summary>
@@ -463,6 +478,34 @@
return undefined;
};
+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 jsonReplacer = function (_, value) {
/// <summary>JSON replacer function for converting a value to its JSON representation.</summary>
/// <param value type="Object">Value to convert.</param>
@@ -479,6 +522,385 @@
}
};
+
+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 };
+};
+
+/// <summary>Creates an object containing information for the context</summary>
+/// ...
+/// <returns type="Object">Object with type information
+/// attribute detectedPayloadKind(optional): see constants starting with PAYLOADTYPE_
+/// attribute deltaKind(optional): deltainformation, one of the following valus DELTATYPE_FEED | DELTATYPE_DELETED_ENTRY | DELTATYPE_LINK | DELTATYPE_DELETED_LINK
+/// attribute typeName(optional): name of the type
+/// attribute type(optional): object containing type information for entity- and complex-types ( null if a typeName is a primitive)
+/// </returns>
+var parseContextUriFragment = function( fragments, model ) {
+ var ret = {};
+
+
+ if (fragments.indexOf('/') === -1 ) {
+ if (fragments.length === 0) {
+ // Capter 10.1
+ ret.detectedPayloadKind = PAYLOADTYPE_SVCDOC;
+ return ret;
+ } else if (fragments === 'Edm.Null') {
+ // Capter 10.15
+ ret.detectedPayloadKind = PAYLOADTYPE_VALUE;
+ ret.isNullProperty = true;
+ return ret;
+ } else if (fragments === 'Collection($ref)') {
+ // Capter 10.11
+ ret.detectedPayloadKind = PAYLOADTYPE_ENTITY_REF_LINKS;
+ return ret;
+ } else if (fragments === '$ref') {
+ // Capter 10.12
+ ret.detectedPayloadKind = PAYLOADTYPE_ENTITY_REF_LINK;
+ return ret;
+ } else {
+ //TODO check for navigation resource
+ }
+ }
+
+ ret.type = undefined;
+ ret.typeName = undefined;
+
+ var fragmentParts = fragments.split("/");
+
+ for(var i = 0; i < fragmentParts.length; ++i) {
+ var fragment = fragmentParts[i];
+ if (ret.typeName === undefined) {
+ //preparation
+ if ( fragment.indexOf('(') !== -1 ) {
+ //remove the query function, cut fragment to matching '('
+ var index = fragment.length - 2 ;
+ for ( var rCount = 1; rCount > 0 && index > 0; --index) {
+ if ( fragment.charAt(index)=='(') {
+ rCount --;
+ } else if ( fragment.charAt(index)==')') {
+ rCount ++;
+ }
+ }
+
+ if (index === 0) {
+ //TODO throw error
+ }
+
+ //remove the projected entity from the fragment; TODO decide if we want to store the projected entity
+ var inPharenthesis = fragment.substring(index+2,fragment.length - 1);
+ fragment = fragment.substring(0,index+1);
+
+ if (utils.startsWith(fragment, 'Collection')) {
+ ret.detectedPayloadKind = PAYLOADTYPE_COLLECTION;
+ // Capter 10.14
+ ret.typeName = inPharenthesis;
+
+ var type = lookupEntityType(ret.typeName, model);
+ if ( type !== null) {
+ ret.type = type;
+ continue;
+ }
+ type = lookupComplexType(ret.typeName, model);
+ if ( type !== null) {
+ ret.type = type;
+ continue;
+ }
+
+ ret.type = null;//in case of #Collection(Edm.String) only lastTypeName is filled
+ continue;
+ } else {
+ // projection: Capter 10.7, 10.8 and 10.9
+ ret.projection = inPharenthesis;
+ }
+ }
+
+ var container = lookupDefaultEntityContainer(model);
+
+ //check for entity
+ var entitySet = lookupEntitySet(container.entitySet, fragment);
+ if ( entitySet !== null) {
+ ret.typeName = entitySet.entityType;
+ ret.type = lookupEntityType( ret.typeName, model);
+ ret.name = fragment;
+ ret.detectedPayloadKind = PAYLOADTYPE_FEED;
+ // Capter 10.2
+ continue;
+ }
+
+ //check for singleton
+ var singleton = lookupSingleton(container.singleton, fragment);
+ if ( singleton !== null) {
+ ret.typeName = singleton.entityType;
+ ret.type = lookupEntityType( ret.typeName, model);
+ ret.name = fragment;
+ ret.detectedPayloadKind = PAYLOADTYPE_ENTRY;
+ // Capter 10.4
+ continue;
+ }
+
+ if (jsonLightIsPrimitiveType(fragment)) {
+ ret.typeName = fragment;
+ ret.type = null;
+ ret.detectedPayloadKind = PAYLOADTYPE_VALUE;
+ continue;
+ }
+
+ //TODO throw ERROR
+ } else {
+ //check for $entity
+ if (utils.endsWith(fragment, '$entity') && (ret.detectedPayloadKind === PAYLOADTYPE_FEED)) {
+ //TODO ret.name = fragment;
+ ret.detectedPayloadKind = PAYLOADTYPE_ENTRY;
+ // Capter 10.3 and 10.6
+ continue;
+ }
+
+ //check for derived types
+ if (fragment.indexOf('.') !== -1) {
+ // Capter 10.6
+ ret.typeName = fragment;
+ var type = lookupEntityType(ret.typeName, model);
+ if ( type !== null) {
+ ret.type = type;
+ continue;
+ }
+ type = lookupComplexType(ret.typeName, model);
+ if ( type !== null) {
+ ret.type = type;
+ continue;
+ }
+
+ //TODO throw ERROR invalid type
+ }
+
+ //check for property value
+ if ( ret.detectedPayloadKind === PAYLOADTYPE_FEED || ret.detectedPayloadKind === PAYLOADTYPE_ENTRY) {
+ var property = lookupProperty(ret.type.property, fragment);
+ if (property !== null) {
+ ret.typeName = property.type;
+ ret.type = lookupComplexType(ret.typeName, model);
+ ret.name = fragment;
+ ret.detectedPayloadKind = PAYLOADTYPE_PROPERTY;
+ // Capter 10.15
+ }
+ continue;
+ }
+
+ if (fragment === '$delta') {
+ ret.deltaKind = DELTATYPE_FEED;
+ continue;
+ } else if (utils.endsWith(fragment, '/$deletedEntity')) {
+ ret.deltaKind = DELTATYPE_DELETED_ENTRY;
+ continue;
+ } else if (utils.endsWith(fragment, '/$link')) {
+ ret.deltaKind = DELTATYPE_LINK;
+ continue;
+ } else if (utils.endsWith(fragment, '/$deletedLink')) {
+ ret.deltaKind = DELTATYPE_DELETED_LINK;
+ continue;
+ }
+ //TODO throw ERROr
+ }
+ }
+ return ret;
+};
+
+var jsonLightPayloadInfo = function (data, model) {
+ /// <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>
+ /// <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 fragment = metadataUri.substring(fragmentStart + 1);
+ return parseContextUriFragment(fragment,model);
+};
+
+var jsonLightReadPayload = function (data, model, demandedFormat,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.detectedPayloadKind) {
+ case PAYLOADTYPE_FEED:
+ return jsonLightReadFeedNew(data, payloadInfo, baseURI, model, demandedFormat,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 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[0].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 jsonLightReadObjectNew = function (data, objectInfo, baseURI, model, demandedFormat, recognizeDates) {
+ //var obj = {};
+
+ data['@odata.type'] = '#'+objectInfo.typeName;
+
+ var keyType = objectInfo.type;
+ while (( keyType.key === undefined) && (keyType.baseType !== undefined)) {
+ keyType = lookupEntityType(keyType.baseType, model);
+ }
+
+ var lastIdSegment = objectInfo.name + jsonLightGetEntryKey(data, keyType);
+ data['@odata.id'] = baseURI.substring(0, baseURI.lastIndexOf("$metadata")) + lastIdSegment;
+ data['@odata.editLink'] = lastIdSegment;
+
+ var serviceURI = baseURI.substring(0, baseURI.lastIndexOf("$metadata"));
+ //jsonLightComputeUrisIfMissing(data, entryInfo, actualType, serviceURI, dataModel, baseTypeModel);
+
+
+
+ for (var name in data) {
+ if (name.indexOf("@") === -1) {
+ var curType = objectInfo.type;
+ var propertyValue = data[name];
+ var property = lookupProperty(curType.property,name); //TODO SK add check for parent type
+
+ while (( property === null) && (curType.baseType !== undefined)) {
+ curType = lookupEntityType(curType.baseType, model);
+ property = lookupProperty(curType.property,name);
+ }
+ if (demandedFormat === 3) {
+ if ( isArray(propertyValue)) {
+ data[name+'@odata.type'] = '#' + property.type;
+ for ( var i = 0; i < propertyValue.length; i++) {
+ jsonLightReadComplexObjectNew(propertyValue[0], property,baseURI,model,demandedFormat, recognizeDates);
+ }
+ } else if (isObject(propertyValue) && (propertyValue!= null)) {
+ jsonLightReadComplexObjectNew(propertyValue, property,baseURI,model,demandedFormat, recognizeDates);
+ } else {
+ data[name+'@odata.type'] = '#' + property.type;
+ }
+
+ } else {
+
+ }
+ }
+ }
+
+ return data;
+};
+
+var jsonLightReadFeedNew = function (data, feedInfo, baseURI, model, demandedFormat,recognizeDates) {
+ var entries = [];
+ var items = data.value;
+ for (i = 0, len = items.length; i < len; i++) {
+ //TODO SK check if items[i] has @odata.type and use this type instead of feedinfo
+
+ if ( items[i]['@odata.type'] !== undefined) {
+ var typeName = items[i]['@odata.type'].substring(1);
+ var type = lookupEntityType( typeName, model);
+ var entryInfo = {
+ contentTypeOdata : feedInfo.contentTypeOdata,
+ detectedPayloadKind : feedInfo.detectedPayloadKind,
+ name : feedInfo.name,
+ type : type,
+ typeName : typeName
+ };
+
+ entry = jsonLightReadObjectNew(items[i], entryInfo, baseURI, model, demandedFormat,recognizeDates);
+ } else {
+ entry = jsonLightReadObjectNew(items[i], feedInfo, baseURI, model, demandedFormat,recognizeDates);
+ }
+
+ entries.push(entry);
+ }
+ data.value = entries;
+ return data;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*
var jsonNormalizeData = function (data, baseURI) {
/// <summary>
/// Normalizes the specified data into an intermediate representation.
@@ -489,8 +911,154 @@
var isSvcDoc = isComplex(data) && !data.__metadata && isArray(data.EntitySets);
return isSvcDoc ? normalizeServiceDocument(data, baseURI) : data;
+};*/
+
+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 jsonLightReadComplexObjectNew = function (data, property, baseURI, model, demandedFormat, recognizeDates) {
+ var type = property.type;
+ if (isCollectionType(property.type)) {
+ type =property.type.substring(11,property.type.length-1);
+ }
+
+ data['@odata.type'] = '#'+type;
+
+
+
+ var propertyType = lookupComplexType(type, model);
+ if (propertyType === null) {
+ return; //TODO check what to do if the type is not known e.g. type #GeometryCollection
+ }
+
+ var curType = propertyType;
+
+
+ for (var name in data) {
+ if (name.indexOf("@") === -1) {
+ var propertyValue = data[name];
+ var property = lookupProperty(curType.property,name); //TODO SK add check for parent type
+
+ while (( property === null) && (curType.baseType !== undefined)) {
+ curType = lookupEntityType(curType.baseType, model);
+ property = lookupProperty(curType.property,name);
+ }
+ if (demandedFormat === 3) {
+ if ( isArray(propertyValue)) {
+ data[name+'@odata.type'] = '#' + property.type;
+ for ( var i = 0; i < propertyValue.length; i++) {
+ jsonLightReadComplexObjectNew(propertyValue[0], property,baseURI,model,demandedFormat, recognizeDates);
+ }
+ } else if (isObject(propertyValue) && (propertyValue!= null)) {
+ jsonLightReadComplexObjectNew(propertyValue, property,baseURI,model,demandedFormat, recognizeDates);
+ } else {
+ data[name+'@odata.type'] = '#' + property.type;
+ }
+
+ } else {
+
+ }
+ }
+ }
+}
+
+
+var jsonLightReadObjectNew = function (data, objectInfo, baseURI, model, demandedFormat, recognizeDates) {
+ //var obj = {};
+
+ data['@odata.type'] = '#'+objectInfo.typeName;
+
+ var keyType = objectInfo.type;
+ while (( keyType.key === undefined) && (keyType.baseType !== undefined)) {
+ keyType = lookupEntityType(keyType.baseType, model);
+ }
+
+ var lastIdSegment = objectInfo.name + jsonLightGetEntryKey(data, keyType);
+ data['@odata.id'] = baseURI.substring(0, baseURI.lastIndexOf("$metadata")) + lastIdSegment;
+ data['@odata.editLink'] = lastIdSegment;
+
+ var serviceURI = baseURI.substring(0, baseURI.lastIndexOf("$metadata"));
+ //jsonLightComputeUrisIfMissing(data, entryInfo, actualType, serviceURI, dataModel, baseTypeModel);
+
+
+
+ for (var name in data) {
+ if (name.indexOf("@") === -1) {
+ var curType = objectInfo.type;
+ var propertyValue = data[name];
+ var property = lookupProperty(curType.property,name); //TODO SK add check for parent type
+
+ while (( property === null) && (curType.baseType !== undefined)) {
+ curType = lookupEntityType(curType.baseType, model);
+ property = lookupProperty(curType.property,name);
+ }
+ if (demandedFormat === 3) {
+ if ( isArray(propertyValue)) {
+ data[name+'@odata.type'] = '#' + property.type;
+ for ( var i = 0; i < propertyValue.length; i++) {
+ jsonLightReadComplexObjectNew(propertyValue[0], property,baseURI,model,demandedFormat, recognizeDates);
+ }
+ } else if (isObject(propertyValue) && (propertyValue!= null)) {
+ jsonLightReadComplexObjectNew(propertyValue, property,baseURI,model,demandedFormat, recognizeDates);
+ } else {
+ data[name+'@odata.type'] = '#' + property.type;
+ }
+
+ } else {
+
+ }
+ }
+ }
+
+ return data;
+};
+
+
var jsonHandler = oDataHandler.handler(jsonParser, jsonSerializer, jsonMediaType, MAX_DATA_SERVICE_VERSION);
jsonHandler.recognizeDates = false;
jsonHandler.useJsonLight = true;
@@ -503,9 +1071,10 @@
// DATAJS INTERNAL START
exports.jsonParser = jsonParser;
exports.jsonSerializer = jsonSerializer;
-exports.jsonNormalizeData = jsonNormalizeData;
-exports.normalizeServiceDocument = normalizeServiceDocument;
+//exports.jsonNormalizeData = jsonNormalizeData;
+//exports.normalizeServiceDocument = normalizeServiceDocument;
exports.parseJsonDateString = parseJsonDateString;
+exports.jsonLightPayloadInfo = jsonLightPayloadInfo;
// DATAJS INTERNAL END