You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ko...@apache.org on 2014/07/15 12:31:10 UTC

[13/20] git commit: [OLINGO-324] modify json.js#jsonParser function

[OLINGO-324] modify json.js#jsonParser function


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/commit/a95a8d33
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/tree/a95a8d33
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/diff/a95a8d33

Branch: refs/heads/master
Commit: a95a8d336b6e58961447b29536cf8963f4418fd5
Parents: 67c9541
Author: Sven Kobler <sv...@sap.com>
Authored: Fri Jun 20 14:42:05 2014 +0200
Committer: Sven Kobler <sv...@sap.com>
Committed: Fri Jun 20 14:42:05 2014 +0200

----------------------------------------------------------------------
 datajs/demo/tester.html            |  11 ++
 datajs/src/lib/datajs/utils.js     |   7 +-
 datajs/src/lib/odata.js            |   2 +
 datajs/src/lib/odata/json-light.js | 175 +++++++++++++++++++++++++-------
 datajs/src/lib/odata/json.js       |  63 ++++++++++--
 5 files changed, 210 insertions(+), 48 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/a95a8d33/datajs/demo/tester.html
----------------------------------------------------------------------
diff --git a/datajs/demo/tester.html b/datajs/demo/tester.html
index 201920d..e1745d0 100644
--- a/datajs/demo/tester.html
+++ b/datajs/demo/tester.html
@@ -32,6 +32,7 @@
         <button id="btnJSON_none">JSON odata.metadata=none</button><br/>
         <button id="btnJSON_minimal">JSON odata.metadata=minimal</button><br/>
         <button id="btnJSON_full">JSON odata.metadata=full</button><br/>
+        <button id="btnJSON_all">JSON odata.metadata=full with extend to all</button><br/>
         <button id="btnMetaData">MetaData</button><br/>
         <button id="btnJSONwithMetaData">JSON with MetaData</button><br/>
         <div id='resultsArea' data-type="json">
@@ -85,6 +86,16 @@
                 OData.read(requestUri, success, errorFunc);
             });
 
+            $('#btnJSON_all').on("click", function(){
+                var requestUri = {
+                    requestUri : 'http://localhost:4002/tests/endpoints/FoodStoreDataServiceV4.svc/Foods',
+                    headers : { Accept : 'application/json;odata.metadata=full' },
+                    extendMetadataToLevel : 'all' ,
+                    recognizeDates : true
+                };
+                var context = { };
+                OData.read(requestUri, success, errorFunc);
+            });
             $('#btnMetaData').on("click", function(){
                 var oHeaders = {
                     'Accept': 'text/html,application/xhtml+xml,application/xml,application/json;odata.metadata=full',

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/a95a8d33/datajs/src/lib/datajs/utils.js
----------------------------------------------------------------------
diff --git a/datajs/src/lib/datajs/utils.js b/datajs/src/lib/datajs/utils.js
index 51f73be..bd4f287 100644
--- a/datajs/src/lib/datajs/utils.js
+++ b/datajs/src/lib/datajs/utils.js
@@ -1,4 +1,4 @@
-/*
+/*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -519,6 +519,10 @@ var concatJsonValueArray = function (data, concatData) {
     return data;
 };
 
+var endsWith = function (input, search) {
+    return input.indexOf(search, input.length - search.length) !== -1;
+};
+
 // DATAJS INTERNAL START
 exports.activeXObject = activeXObject;
 exports.assigned = assigned;
@@ -544,6 +548,7 @@ exports.convertByteArrayToHexString = convertByteArrayToHexString;
 exports.getJsonValueArraryLength = getJsonValueArraryLength;
 exports.sliceJsonValueArray = sliceJsonValueArray;
 exports.concatJsonValueArray = concatJsonValueArray;
+exports.endsWith = endsWith;
 // DATAJS INTERNAL END
 
     
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/a95a8d33/datajs/src/lib/odata.js
----------------------------------------------------------------------
diff --git a/datajs/src/lib/odata.js b/datajs/src/lib/odata.js
index 47cc503..297a339 100644
--- a/datajs/src/lib/odata.js
+++ b/datajs/src/lib/odata.js
@@ -138,6 +138,7 @@ exports.request = function (request, success, error, handler, httpClient, metada
 
     // Augment the request with additional defaults.
     request.recognizeDates = utils.defined(request.recognizeDates, odataJson.jsonHandler.recognizeDates);
+    request.extendMetadataToLevel = utils.defined(request.extendMetadataToLevel, odataJson.jsonHandler.extendMetadataToLevel);
     request.callbackParameterName = utils.defined(request.callbackParameterName, odataNet.defaultHttpClient.callbackParameterName);
     request.formatQueryString = utils.defined(request.formatQueryString, odataNet.defaultHttpClient.formatQueryString);
     request.enableJsonpCallback = utils.defined(request.enableJsonpCallback, odataNet.defaultHttpClient.enableJsonpCallback);
@@ -146,6 +147,7 @@ exports.request = function (request, success, error, handler, httpClient, metada
     var context = {
         metadata: metadata,
         recognizeDates: request.recognizeDates,
+        extendMetadataToLevel : request.extendMetadataToLevel,
         callbackParameterName: request.callbackParameterName,
         formatQueryString: request.formatQueryString,
         enableJsonpCallback: request.enableJsonpCallback,

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/a95a8d33/datajs/src/lib/odata/json-light.js
----------------------------------------------------------------------
diff --git a/datajs/src/lib/odata/json-light.js b/datajs/src/lib/odata/json-light.js
index 9c4c079..17c2cba 100644
--- a/datajs/src/lib/odata/json-light.js
+++ b/datajs/src/lib/odata/json-light.js
@@ -69,12 +69,28 @@ var parseDuration = oDataUtils.parseDuration;
 
 // CONTENT START
 
-var PAYLOADTYPE_OBJECT = "o";
 var PAYLOADTYPE_FEED = "f";
-var PAYLOADTYPE_PRIMITIVE = "p";
+var PAYLOADTYPE_ENTRY = "e";
+var PAYLOADTYPE_PROPERTY = "p";
+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_LINKS = "l";
+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";
+var DELTATYPE_DELETED_LINK = "dl";
 
 var odataNs = "odata";
 var odataAnnotationPrefix = odataNs + ".";
@@ -1036,57 +1052,93 @@ var jsonLightMakePayloadInfo = function (kind, type) {
     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 parseContextUriFragment = function( fragment ) {
+    var ret = {};
+
+    ret.deltaKind = undefined;
+    if (utils.endsWith(fragment, '/$entity')) {
+        fragment = fragment.substring(fragment.lenght - 8);
+    } else if (utils.endsWith(fragment, '/$delta')) {
+        ret.deltaKind = DELTATYPE_FEED;
+        fragment = fragment.substring(fragment.lenght - 7);
+    } else if (utils.endsWith(fragment, '/$deletedEntity')) {
+        ret.deltaKind = DELTATYPE_DELETED_ENTRY;
+        fragment = fragment.substring(fragment.lenght - 15);
+    } else if (utils.endsWith(fragment, '/$link')) {
+        ret.deltaKind = DELTATYPE_LINK;
+        fragment = fragment.substring(fragment.lenght - 6);
+    } else if (utils.endsWith(fragment, '/$deletedLink')) {
+        ret.deltaKind = DELTATYPE_DELETED_LINK;
+        fragment = fragment.substring(fragment.lenght - 13);
+    }
+
+    if (utils.endsWith(fragment,")")) {
+        //remove the query function, cut fragment to matching '('
+        var index = fragment.lenght - 2 ;
+        for ( var rCount = 1; rcount > 0 && index > 0; --index) {
+            if ( fragment.charAt(index)=='(') {
+                rCount ++;
+            } else if ( fragment.charAt(index)==')') {
+                rCount --;    
+            }
+        }
 
-    var metadataUri = data[contextUrlAnnotation];
-    if (!metadataUri || typeof metadataUri !== "string") {
-        return null;
-    }
+        if (index == 0) {
+            //TODO throw error
+        }
 
-    var fragmentStart = metadataUri.lastIndexOf("#");
-    if (fragmentStart === -1) {
-        return jsonLightMakePayloadInfo(PAYLOADTYPE_SVCDOC);
-    }
+        var previous = fragment.substring(0, index + 1);
 
-    var elementStart = metadataUri.indexOf("@Element", fragmentStart);
-    var fragmentEnd = elementStart - 1;
 
-    if (fragmentEnd < 0) {
-        fragmentEnd = metadataUri.indexOf("?", fragmentStart);
-        if (fragmentEnd === -1) {
-            fragmentEnd = metadataUri.length;
+        if (previous !== 'Collection') { // Don't treat Collection(Edm.Type) as SelectExpand segment
+            var selectExpandStr = fragment.substring(index+2, fragment.lenght - 1);
+            var keyPattern = /^(?:-{0,1}\d+?|\w*'.+?'|[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}|.+?=.+?)$/;
+            var matches = keyPattern.exec(selectExpandStr);
+            if ( matches ) {
+                 //TODO throw error
+            }
+
+            ret.selectQueryOptionString = selectExpandStr;
+            fragment = previous;
         }
-    }
 
-    var fragment = metadataUri.substring(fragmentStart + 1, fragmentEnd);
-    if (fragment.indexOf("/$links/") > 0) {
-        return jsonLightMakePayloadInfo(PAYLOADTYPE_LINKS);
     }
 
+    ret.detectedPayloadKind = undefined;
+    if (fragment.indexOf('/') === -1 ) {
+        if (fragment.length === 0) {
+            // Capter 10.1
+            ret.detectedPayloadKind = PAYLOADTYPE_SVCDOC;
+        } else if (fragment === 'Edm.Null') {
+            // Capter 10.15
+            ret.detectedPayloadKind = PAYLOADTYPE_PROPERTY;
+            ret.isNullProperty = true;
+        } else if (fragment === 'Collection($ref)') {
+            // Capter 10.11
+            ret.detectedPayloadKind = PAYLOADTYPE_ENTITY_REF_LINKS;
+        } else if (fragment === '$ref') {
+            // Capter 10.12
+            ret.detectedPayloadKind = PAYLOADTYPE_ENTITY_REF_LINK;
+        } else {
+            //TODO check for navigation resource
+        }
+    } 
+
+    // split fragment at '/'
+    //TODO changes
     var fragmentParts = fragment.split("/");
     if (fragmentParts.length >= 0) {
         var qualifiedName = fragmentParts[0];
         var typeCast = fragmentParts[1];
 
         if (jsonLightIsPrimitiveType(qualifiedName)) {
-            return jsonLightMakePayloadInfo(PAYLOADTYPE_PRIMITIVE, qualifiedName);
+            ret.detectedPayloadKind  = PAYLOADTYPE_VALUE;
+            return ret;
         }
 
         if (isCollectionType(qualifiedName)) {
-            return jsonLightMakePayloadInfo(PAYLOADTYPE_COLLECTION, qualifiedName);
+            return ret;
         }
 
         var entityType = typeCast;
@@ -1107,7 +1159,7 @@ var jsonLightPayloadInfo = function (data, model, inferFeedAsComplexType) {
         }
 
         var info;
-        if (elementStart > 0) {
+        if (d > 0) {
             info = jsonLightMakePayloadInfo(PAYLOADTYPE_OBJECT, entityType);
             info.entitySet = entitySet;
             info.functionImport = functionImport;
@@ -1135,7 +1187,52 @@ var jsonLightPayloadInfo = function (data, model, inferFeedAsComplexType) {
         return jsonLightMakePayloadInfo(PAYLOADTYPE_OBJECT, qualifiedName);
     }
 
-    return null;
+};
+
+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 d = 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);
+
+    return;
+
+
 };
 
 var jsonLightReadPayload = function (data, model, recognizeDates, inferFeedAsComplexType, contentTypeOdata) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/a95a8d33/datajs/src/lib/odata/json.js
----------------------------------------------------------------------
diff --git a/datajs/src/lib/odata/json.js b/datajs/src/lib/odata/json.js
index 28e71fd..c33104d 100644
--- a/datajs/src/lib/odata/json.js
+++ b/datajs/src/lib/odata/json.js
@@ -257,6 +257,7 @@ var jsonParser = function (handler, text, context) {
     } catch(err) {
         payloadFormat = 1;
     }
+    payloadFormat = (payloadFormat === undefined) ? 1 : payloadFormat;
 
     var demandedFormat = 1;//minmal
     try {
@@ -264,6 +265,9 @@ var jsonParser = function (handler, text, context) {
     } catch(err) {
         demandedFormat = 1;
     }
+    demandedFormat = (demandedFormat === undefined) ? 1 : demandedFormat;
+
+    //return jsonLightReadPayload(json, model, recognizeDates, inferJsonLightFeedAsObject, context.contentType.properties['odata.metadata']);
 
     if ( payloadFormat >= demandedFormat) {
         if (recognizeDates) {
@@ -273,7 +277,8 @@ var jsonParser = function (handler, text, context) {
         }
     } else {
         if (payloadFormat === 2) { //full, no metadata in context required
-            //insert the missing type information for strings
+            //insert the missing type information for strings, bool, etc.
+            //guess type for nummber as defined in the odata-json-format-v4.0.doc specification
             return extendMetadataFromPayload(json,context,recognizeDates);
         } else if (payloadFormat === 1) { //minmal
             if (utils.isArray(context.metadata)) {
@@ -288,18 +293,60 @@ var jsonParser = function (handler, text, context) {
         }
     }
 
-    //return jsonLightReadPayload(json, model, recognizeDates, inferJsonLightFeedAsObject, context.contentType.properties['odata.metadata']);
+    
 };
 
 var convertPrimitivetypesGeneric = function(json,context) {
-    return json;
-}
-var extendMetadataFromPayload = function(json,context,recognizeDates) {
-    return json;
-}
+    
+};
+
+
+var addType = function(data, name, value ) {
+    var fullName = name+'@odata.type';
+
+    if ( data[fullName] === undefined) {
+        data[fullName] = value;
+    }
+};
+
+var extendMetadataFromPayload = function(data,context,recognizeDates) {
+    if ( utils.isObject(data) ) {
+
+        for (var key in data) {
+            if (data.hasOwnProperty(key)) {
+                if (key.indexOf('@') === -1) {
+                    if (utils.isArray(data[key])) {
+                        for ( var i = 0; i < data[key].length; ++i) {
+                            extendMetadataFromPayload(data[key][i], context, recognizeDates);
+                        }
+                    } else if (utils.isObject(data[key])) {
+                        if (data[key] !== null) {
+                            extendMetadataFromPayload(data[key],context, recognizeDates);
+                        }
+                    } else {
+                        var type = typeof data[key];
+                        if ( type === 'string' ) {
+                           addType(data,key,'#String');
+                        } else if (type ==='boolean') {
+                            addType(data,key,'#Bool');
+                        } else if (type ==='number') {
+                            if ( data[key] % 1 === 0 ) {
+                                addType(data,key,'#Integer');
+                            } else {
+                                addType(data,key,'#Decimal');
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return data;
+};
+
 var extendMetadataFromContext = function(json,context,recognizeDates) {
     return json;
-}
+};
 
 
 var jsonToString = function (data) {