From 06fc05249894e9e25a0f6cfb7d2e71a61f8dd3e6 Mon Sep 17 00:00:00 2001 From: Mark Lesswing Date: Fri, 21 Mar 2014 10:33:34 -0500 Subject: [PATCH 01/33] Change to allow startsWith to be supported instead of just startswith --- oDataParser/RequestParser.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/oDataParser/RequestParser.js b/oDataParser/RequestParser.js index cc211450..c30984bb 100644 --- a/oDataParser/RequestParser.js +++ b/oDataParser/RequestParser.js @@ -566,7 +566,9 @@ var srcIndex = this.lexer.srcIndex; if (token.tokenType != TokenType.WORD) return; - var name = token.value; + + var name = token.value.toLowerCase(); + for (var i = 0; i < this.reservedNs.length; i++) { if (this.reservedNs[i] == name) { From 611be8eea497a238ff6381f338c9a016c36766b0 Mon Sep 17 00:00:00 2001 From: Mark Lesswing Date: Fri, 21 Mar 2014 10:36:50 -0500 Subject: [PATCH 02/33] Added hooks to add and remove items from the external index as well as to trace work performed on add, query and delete --- JayService/JSObjectAdapter.js | 10 +++++ JayService/OData/BatchProcessor.js | 12 +++++- JayService/OData/EntitySetProcessor.js | 11 +++++- Types/EntitySet.js | 54 ++++++++++++++++++++++++-- 4 files changed, 80 insertions(+), 7 deletions(-) diff --git a/JayService/JSObjectAdapter.js b/JayService/JSObjectAdapter.js index 8a39ab06..5d43ed7c 100644 --- a/JayService/JSObjectAdapter.js +++ b/JayService/JSObjectAdapter.js @@ -57,6 +57,10 @@ $data.Class.define("$data.JSObjectAdapter", null, null, { var methodArgs = self.resolveArguments(req, serviceInstance, memberInfo); if (memberInfo.method instanceof Array ? memberInfo.method.indexOf(req.method) >= 0 : memberInfo.method === req.method){ + + req.reso.memberName = memberName; + req.reso.namespace = "System"; + oDataBuilderCfg = { version: 'V2', baseUrl: req.fullRoute, @@ -78,6 +82,9 @@ $data.Class.define("$data.JSObjectAdapter", null, null, { if (member) { var esProc = new $data.JayService.OData.EntitySetProcessor(memberName, serviceInstance, { top: serviceInstance.storageProvider.providerConfiguration.responseLimit || $data.JayService.OData.Defaults.defaultResponseLimit }); + req.reso.memberName = memberName; + req.reso.namespace = member.elementType.namespace; + oDataBuilderCfg = { version: 'V2', baseUrl: req.fullRoute, @@ -344,6 +351,9 @@ $data.Class.define("$data.JSObjectAdapter", null, null, { defer.resolve(new $data.EmptyServiceResult(404)); } } else { + + request.reso.resultSize = 1; + defer.resolve(result); } diff --git a/JayService/OData/BatchProcessor.js b/JayService/OData/BatchProcessor.js index 12b217ec..642f7f0e 100644 --- a/JayService/OData/BatchProcessor.js +++ b/JayService/OData/BatchProcessor.js @@ -179,7 +179,11 @@ this._discoverNavigations(changeRequest, referenceData, itemType); var entity = new itemType(changeRequest.data, { converters: $data.oDataConverter.fromDb }); referenceData[refId].resultObject = entity; - setInfo.set.add(entity); + + request.reso.memberName = setInfo.set.name; + request.reso.namespace = itemType.namespace; + setInfo.set.add(entity, request); + break; case 'MERGE': case 'PATCH': @@ -199,7 +203,11 @@ case 'DELETE': var entity = new itemType(setInfo.idObj); referenceData[refId].resultObject = entity; - setInfo.set.remove(entity); + + request.reso.memberName = setInfo.set.name; + request.reso.namespace = itemType.namespace; + setInfo.set.remove(entity, request); + break; default: break; diff --git a/JayService/OData/EntitySetProcessor.js b/JayService/OData/EntitySetProcessor.js index c462b7a5..054db6d6 100644 --- a/JayService/OData/EntitySetProcessor.js +++ b/JayService/OData/EntitySetProcessor.js @@ -59,7 +59,9 @@ } var entity = new this.entitySet.createNew(bodyData, { converters: $data.oDataConverter.fromDb }); - this.entitySet.add(entity); + + this.entitySet.add(entity, req); + this.context.saveChanges({ success: function () { res.statusCode = 201; @@ -127,7 +129,9 @@ self.BatchDeleteFromEntitySet(req, config, cbWrapper); } else { if (this.member.idObject) { - this.entitySet.remove(this.member.idObject); + + this.entitySet.remove(this.member.idObject, req); + this.context.saveChanges({ success: function () { //return with no content @@ -191,6 +195,9 @@ config.includes = result.includes; this.context.executeQuery(new $data.Queryable(this.entitySet, result.expression), { success: function (contextResult) { + + req.reso.resultSize = contextResult.length; + if (self.member.valueRequeset) { // request pattern: /EntitySet(key)/Field/$value self.prepareSimpleResponse(contextResult, self.member.selectedField, self.entitySet, callback); diff --git a/Types/EntitySet.js b/Types/EntitySet.js index 36c31365..87898a1a 100644 --- a/Types/EntitySet.js +++ b/Types/EntitySet.js @@ -1,3 +1,6 @@ + +var fs = require('fs'); + ///EntitySet is responsible for /// -creating and holding entityType through schema /// - provide Add method @@ -66,7 +69,7 @@ $data.Class.defineEx('$data.EntitySet', } trackedEntities.push({ entitySet: this, data: entity }); }, - add: function (entity) { + add: function (entity, req) { /// /// Creates a typed entity and adds to the context. /// The init parameters whish is based on Entity @@ -101,7 +104,28 @@ $data.Class.defineEx('$data.EntitySet', data.entityState = $data.EntityState.Added; data.changedProperties = undefined; data.context = this.entityContext; - this._trackEntity(data); + + if (req.reso.externalIndex) { + var keyName =this.elementType.memberDefinitions.getKeyProperties()[0].name; + var keyValue = data[keyName]; + if (INDEX.indexOf(keyValue) == -1) { + INDEX[INDEX.length] = keyValue; + fs.writeFile(req.reso.indexFileName, INDEX.toString(), function(err) { + if (err) throw err; + }); + req.reso.resultSize = 1; + req.reso.keyValue = keyValue; + this._trackEntity(data); +//console.dir(data); +// } else { +//console.log("Item with a " + keyName + " of " + keyValue + " already exists. Not added"); + } + } else { +console.log("INDEX IS OFF"); + this._trackEntity(data); + } + + return data; }, @@ -113,7 +137,7 @@ $data.Class.defineEx('$data.EntitySet', }); return result; }, - remove: function (entity) { + remove: function (entity, req) { /// /// Creates a typed entity and marks it as Deleted. /// The init parameters whish is based on Entity @@ -145,6 +169,30 @@ $data.Class.defineEx('$data.EntitySet', data = new this.createNew(entity); } data.entityState = $data.EntityState.Deleted; + + if (req.reso.externalIndex) { + var keyName =this.elementType.memberDefinitions.getKeyProperties()[0].name; + if (entity[keyName]) { + var keyValue = entity[keyName]; + req.reso.resultSize = 1; + req.reso.keyValue = entity[keyName]; + var position = INDEX.indexOf(keyValue); + if (position != -1) { + INDEX.splice(position,1); + if (INDEX.length > 0) { + fs.writeFile(req.reso.indexFileName, INDEX.toString(), function(err) { + if (err) throw err; + }); + } else { + fs.unlinkSync(req.reso.indexFileName); + } + } + } + } else { +console.log("INDEX IS OFF"); + } + + data.changedProperties = undefined; this._trackEntity(data); }, From a68cf7e7862e141d86ad517b046e5c03cb502f07 Mon Sep 17 00:00:00 2001 From: Mark Lesswing Date: Fri, 21 Mar 2014 10:37:35 -0500 Subject: [PATCH 03/33] Added EXAMPLE of how to extend functions to an entity --- Types/Entity.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Types/Entity.js b/Types/Entity.js index f466ef34..6830c12b 100644 --- a/Types/Entity.js +++ b/Types/Entity.js @@ -514,6 +514,14 @@ $data.Entity = Entity = $data.Class.define("$data.Entity", null, null, { } return '#'; } +// +// EXAMPLE of how to add function calls +// +// }, +// findKeyName: function(es) { +// return es.memberDefinitions.getKeyProperties()[0].name; +// } + }, { //create get_[property] and set_[property] functions for properties From 1397c91a869c4789a1454c30f738126538946f54 Mon Sep 17 00:00:00 2001 From: Mark Lesswing Date: Fri, 21 Mar 2014 16:50:39 -0500 Subject: [PATCH 04/33] cleanup of filed from the fork process --- release/jaydata-vsdoc.js | 17287 ---------------- release/jaydata.js | 17273 --------------- release/jaydata.min.js | 632 - release/jaydatamodules/angular.js | 249 - release/jaydatamodules/angular.min.js | 21 - release/jaydatamodules/deferred.js | 47 - release/jaydatamodules/deferred.min.js | 15 - release/jaydatamodules/errorhandler.js | 35 - release/jaydatamodules/errorhandler.min.js | 14 - release/jaydatamodules/formBinder.js | 121 - release/jaydatamodules/formBinder.min.js | 15 - release/jaydatamodules/handlebars.js | 367 - release/jaydatamodules/handlebars.min.js | 23 - release/jaydatamodules/inMemory.js | 45 - release/jaydatamodules/inMemory.min.js | 15 - release/jaydatamodules/jaydata.mscrm.js | 160 - release/jaydatamodules/jaydata.mscrm.min.js | 19 - .../jaydatamodules/jaydata.mscrm.server.js | 44 - .../jaydata.mscrm.server.min.js | 15 - release/jaydatamodules/kendo.js | 724 - release/jaydatamodules/kendo.min.js | 32 - release/jaydatamodules/knockout.js | 450 - release/jaydatamodules/knockout.min.js | 28 - release/jaydatamodules/qDeferred.js | 77 - release/jaydatamodules/qDeferred.min.js | 15 - release/jaydatamodules/sencha.js | 136 - release/jaydatamodules/sencha.min.js | 17 - release/jaydatamodules/template.js | 83 - release/jaydatamodules/template.min.js | 16 - release/jaydatamodules/validate.js | 166 - release/jaydatamodules/validate.min.js | 19 - release/jaydataproviders/FacebookProvider.js | 724 - .../jaydataproviders/FacebookProvider.min.js | 53 - release/jaydataproviders/InMemoryProvider.js | 708 - .../jaydataproviders/InMemoryProvider.min.js | 49 - release/jaydataproviders/IndexedDbProvider.js | 782 - .../jaydataproviders/IndexedDbProvider.min.js | 46 - release/jaydataproviders/MongoDbProvider.js | 2313 --- .../jaydataproviders/MongoDbProvider.min.js | 132 - release/jaydataproviders/SqLiteProvider.js | 2105 -- .../jaydataproviders/SqLiteProvider.min.js | 114 - release/jaydataproviders/StormProvider.js | 256 - release/jaydataproviders/StormProvider.min.js | 24 - release/jaydataproviders/WebApiProvider.js | 1433 -- .../jaydataproviders/WebApiProvider.min.js | 77 - release/jaydataproviders/YQLProvider.js | 874 - release/jaydataproviders/YQLProvider.min.js | 63 - release/jaydataproviders/oDataProvider.js | 1962 -- release/jaydataproviders/oDataProvider.min.js | 113 - 49 files changed, 49988 deletions(-) delete mode 100644 release/jaydata-vsdoc.js delete mode 100644 release/jaydata.js delete mode 100644 release/jaydata.min.js delete mode 100644 release/jaydatamodules/angular.js delete mode 100644 release/jaydatamodules/angular.min.js delete mode 100644 release/jaydatamodules/deferred.js delete mode 100644 release/jaydatamodules/deferred.min.js delete mode 100644 release/jaydatamodules/errorhandler.js delete mode 100644 release/jaydatamodules/errorhandler.min.js delete mode 100644 release/jaydatamodules/formBinder.js delete mode 100644 release/jaydatamodules/formBinder.min.js delete mode 100644 release/jaydatamodules/handlebars.js delete mode 100644 release/jaydatamodules/handlebars.min.js delete mode 100644 release/jaydatamodules/inMemory.js delete mode 100644 release/jaydatamodules/inMemory.min.js delete mode 100644 release/jaydatamodules/jaydata.mscrm.js delete mode 100644 release/jaydatamodules/jaydata.mscrm.min.js delete mode 100644 release/jaydatamodules/jaydata.mscrm.server.js delete mode 100644 release/jaydatamodules/jaydata.mscrm.server.min.js delete mode 100644 release/jaydatamodules/kendo.js delete mode 100644 release/jaydatamodules/kendo.min.js delete mode 100644 release/jaydatamodules/knockout.js delete mode 100644 release/jaydatamodules/knockout.min.js delete mode 100644 release/jaydatamodules/qDeferred.js delete mode 100644 release/jaydatamodules/qDeferred.min.js delete mode 100644 release/jaydatamodules/sencha.js delete mode 100644 release/jaydatamodules/sencha.min.js delete mode 100644 release/jaydatamodules/template.js delete mode 100644 release/jaydatamodules/template.min.js delete mode 100644 release/jaydatamodules/validate.js delete mode 100644 release/jaydatamodules/validate.min.js delete mode 100644 release/jaydataproviders/FacebookProvider.js delete mode 100644 release/jaydataproviders/FacebookProvider.min.js delete mode 100644 release/jaydataproviders/InMemoryProvider.js delete mode 100644 release/jaydataproviders/InMemoryProvider.min.js delete mode 100644 release/jaydataproviders/IndexedDbProvider.js delete mode 100644 release/jaydataproviders/IndexedDbProvider.min.js delete mode 100644 release/jaydataproviders/MongoDbProvider.js delete mode 100644 release/jaydataproviders/MongoDbProvider.min.js delete mode 100644 release/jaydataproviders/SqLiteProvider.js delete mode 100644 release/jaydataproviders/SqLiteProvider.min.js delete mode 100644 release/jaydataproviders/StormProvider.js delete mode 100644 release/jaydataproviders/StormProvider.min.js delete mode 100644 release/jaydataproviders/WebApiProvider.js delete mode 100644 release/jaydataproviders/WebApiProvider.min.js delete mode 100644 release/jaydataproviders/YQLProvider.js delete mode 100644 release/jaydataproviders/YQLProvider.min.js delete mode 100644 release/jaydataproviders/oDataProvider.js delete mode 100644 release/jaydataproviders/oDataProvider.min.js diff --git a/release/jaydata-vsdoc.js b/release/jaydata-vsdoc.js deleted file mode 100644 index 21e89922..00000000 --- a/release/jaydata-vsdoc.js +++ /dev/null @@ -1,17287 +0,0 @@ -// JayData 1.3.6 -// Dual licensed under MIT and GPL v2 -// Copyright JayStack Technologies (http://jaydata.org/licensing) -// -// JayData is a standards-based, cross-platform Javascript library and a set of -// practices to access and manipulate data from various online and offline sources. -// -// Credits: -// Hajnalka Battancs, Dániel József, János Roden, László Horváth, Péter Nochta -// Péter Zentai, Róbert Bónay, Szabolcs Czinege, Viktor Borza, Viktor Lázár, -// Zoltán Gyebrovszki, Gábor Dolla -// -// More info: http://jaydata.org -/* - -IMPORTANT: -!!! Do not reference this file to html! !!! - -*/ - -(function (window) { - if (typeof window.intellisense === 'undefined') { - window.intellisense = { - annotate: function () { }, - logMessage: function () { } - }; - } -})(window);// Acorn is a tiny, fast JavaScript parser written in JavaScript. -// -// Acorn was written by Marijn Haverbeke and released under an MIT -// license. The Unicode regexps (for identifiers and whitespace) were -// taken from [Esprima](http://esprima.org) by Ariya Hidayat. -// -// Git repositories for Acorn are available at -// -// http://marijnhaverbeke.nl/git/acorn -// https://github.com/marijnh/acorn.git -// -// Please use the [github bug tracker][ghbt] to report issues. -// -// [ghbt]: https://github.com/marijnh/acorn/issues -// -// This file defines the main parser interface. The library also comes -// with a [error-tolerant parser][dammit] and an -// [abstract syntax tree walker][walk], defined in other files. -// -// [dammit]: acorn_loose.js -// [walk]: util/walk.js - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") return mod(exports); // CommonJS - if (typeof define == "function" && define.amd) return define(["exports"], mod); // AMD - mod(self.acorn || (self.acorn = {})); // Plain browser env -})(function(exports) { - "use strict"; - - exports.version = "0.1.01"; - - // The main exported interface (under `self.acorn` when in the - // browser) is a `parse` function that takes a code string and - // returns an abstract syntax tree as specified by [Mozilla parser - // API][api], with the caveat that the SpiderMonkey-specific syntax - // (`let`, `yield`, inline XML, etc) is not recognized. - // - // [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API - - var options, input, inputLen, sourceFile; - - exports.parse = function(inpt, opts) { - input = String(inpt); inputLen = input.length; - setOptions(opts); - initTokenState(); - return parseTopLevel(options.program); - }; - - // A second optional argument can be given to further configure - // the parser process. These options are recognized: - - var defaultOptions = exports.defaultOptions = { - // `ecmaVersion` indicates the ECMAScript version to parse. Must - // be either 3 or 5. This - // influences support for strict mode, the set of reserved words, and - // support for getters and setter. - ecmaVersion: 5, - // Turn on `strictSemicolons` to prevent the parser from doing - // automatic semicolon insertion. - strictSemicolons: false, - // When `allowTrailingCommas` is false, the parser will not allow - // trailing commas in array and object literals. - allowTrailingCommas: true, - // By default, reserved words are not enforced. Enable - // `forbidReserved` to enforce them. - forbidReserved: false, - // When `locations` is on, `loc` properties holding objects with - // `start` and `end` properties in `{line, column}` form (with - // line being 1-based and column 0-based) will be attached to the - // nodes. - locations: false, - // A function can be passed as `onComment` option, which will - // cause Acorn to call that function with `(block, text, start, - // end)` parameters whenever a comment is skipped. `block` is a - // boolean indicating whether this is a block (`/* */`) comment, - // `text` is the content of the comment, and `start` and `end` are - // character offsets that denote the start and end of the comment. - // When the `locations` option is on, two more parameters are - // passed, the full `{line, column}` locations of the start and - // end of the comments. - onComment: null, - // Nodes have their start and end characters offsets recorded in - // `start` and `end` properties (directly on the node, rather than - // the `loc` object, which holds line/column data. To also add a - // [semi-standardized][range] `range` property holding a `[start, - // end]` array with the same numbers, set the `ranges` option to - // `true`. - // - // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678 - ranges: false, - // It is possible to parse multiple files into a single AST by - // passing the tree produced by parsing the first file as - // `program` option in subsequent parses. This will add the - // toplevel forms of the parsed file to the `Program` (top) node - // of an existing parse tree. - program: null, - // When `location` is on, you can pass this to record the source - // file in every node's `loc` object. - sourceFile: null - }; - - function setOptions(opts) { - options = opts || {}; - for (var opt in defaultOptions) if (!options.hasOwnProperty(opt)) - options[opt] = defaultOptions[opt]; - sourceFile = options.sourceFile || null; - } - - // The `getLineInfo` function is mostly useful when the - // `locations` option is off (for performance reasons) and you - // want to find the line/column position for a given character - // offset. `input` should be the code string that the offset refers - // into. - - var getLineInfo = exports.getLineInfo = function(input, offset) { - for (var line = 1, cur = 0;;) { - lineBreak.lastIndex = cur; - var match = lineBreak.exec(input); - if (match && match.index < offset) { - ++line; - cur = match.index + match[0].length; - } else break; - } - return {line: line, column: offset - cur}; - }; - - // Acorn is organized as a tokenizer and a recursive-descent parser. - // The `tokenize` export provides an interface to the tokenizer. - // Because the tokenizer is optimized for being efficiently used by - // the Acorn parser itself, this interface is somewhat crude and not - // very modular. Performing another parse or call to `tokenize` will - // reset the internal state, and invalidate existing tokenizers. - - exports.tokenize = function(inpt, opts) { - input = String(inpt); inputLen = input.length; - setOptions(opts); - initTokenState(); - - var t = {}; - function getToken(forceRegexp) { - readToken(forceRegexp); - t.start = tokStart; t.end = tokEnd; - t.startLoc = tokStartLoc; t.endLoc = tokEndLoc; - t.type = tokType; t.value = tokVal; - return t; - } - getToken.jumpTo = function(pos, reAllowed) { - tokPos = pos; - if (options.locations) { - tokCurLine = tokLineStart = lineBreak.lastIndex = 0; - var match; - while ((match = lineBreak.exec(input)) && match.index < pos) { - ++tokCurLine; - tokLineStart = match.index + match[0].length; - } - } - var ch = input.charAt(pos - 1); - tokRegexpAllowed = reAllowed; - skipSpace(); - }; - return getToken; - }; - - // State is kept in (closure-)global variables. We already saw the - // `options`, `input`, and `inputLen` variables above. - - // The current position of the tokenizer in the input. - - var tokPos; - - // The start and end offsets of the current token. - - var tokStart, tokEnd; - - // When `options.locations` is true, these hold objects - // containing the tokens start and end line/column pairs. - - var tokStartLoc, tokEndLoc; - - // The type and value of the current token. Token types are objects, - // named by variables against which they can be compared, and - // holding properties that describe them (indicating, for example, - // the precedence of an infix operator, and the original name of a - // keyword token). The kind of value that's held in `tokVal` depends - // on the type of the token. For literals, it is the literal value, - // for operators, the operator name, and so on. - - var tokType, tokVal; - - // Interal state for the tokenizer. To distinguish between division - // operators and regular expressions, it remembers whether the last - // token was one that is allowed to be followed by an expression. - // (If it is, a slash is probably a regexp, if it isn't it's a - // division operator. See the `parseStatement` function for a - // caveat.) - - var tokRegexpAllowed; - - // When `options.locations` is true, these are used to keep - // track of the current line, and know when a new line has been - // entered. - - var tokCurLine, tokLineStart; - - // These store the position of the previous token, which is useful - // when finishing a node and assigning its `end` position. - - var lastStart, lastEnd, lastEndLoc; - - // This is the parser's state. `inFunction` is used to reject - // `return` statements outside of functions, `labels` to verify that - // `break` and `continue` have somewhere to jump to, and `strict` - // indicates whether strict mode is on. - - var inFunction, labels, strict; - - // This function is used to raise exceptions on parse errors. It - // takes an offset integer (into the current `input`) to indicate - // the location of the error, attaches the position to the end - // of the error message, and then raises a `SyntaxError` with that - // message. - - function raise(pos, message) { - var loc = getLineInfo(input, pos); - message += " (" + loc.line + ":" + loc.column + ")"; - var err = new SyntaxError(message); - err.pos = pos; err.loc = loc; err.raisedAt = tokPos; - throw err; - } - - // ## Token types - - // The assignment of fine-grained, information-carrying type objects - // allows the tokenizer to store the information it has about a - // token in a way that is very cheap for the parser to look up. - - // All token type variables start with an underscore, to make them - // easy to recognize. - - // These are the general types. The `type` property is only used to - // make them recognizeable when debugging. - - var _num = {type: "num"}, _regexp = {type: "regexp"}, _string = {type: "string"}; - var _name = {type: "name"}, _eof = {type: "eof"}; - - // Keyword tokens. The `keyword` property (also used in keyword-like - // operators) indicates that the token originated from an - // identifier-like word, which is used when parsing property names. - // - // The `beforeExpr` property is used to disambiguate between regular - // expressions and divisions. It is set on all token types that can - // be followed by an expression (thus, a slash after them would be a - // regular expression). - // - // `isLoop` marks a keyword as starting a loop, which is important - // to know when parsing a label, in order to allow or disallow - // continue jumps to that label. - - var _break = {keyword: "break"}, _case = {keyword: "case", beforeExpr: true}, _catch = {keyword: "catch"}; - var _continue = {keyword: "continue"}, _debugger = {keyword: "debugger"}, _default = {keyword: "default"}; - var _do = {keyword: "do", isLoop: true}, _else = {keyword: "else", beforeExpr: true}; - var _finally = {keyword: "finally"}, _for = {keyword: "for", isLoop: true}, _function = {keyword: "function"}; - var _if = {keyword: "if"}, _return = {keyword: "return", beforeExpr: true}, _switch = {keyword: "switch"}; - var _throw = {keyword: "throw", beforeExpr: true}, _try = {keyword: "try"}, _var = {keyword: "var"}; - var _while = {keyword: "while", isLoop: true}, _with = {keyword: "with"}, _new = {keyword: "new", beforeExpr: true}; - var _this = {keyword: "this"}; - - // The keywords that denote values. - - var _null = {keyword: "null", atomValue: null}, _true = {keyword: "true", atomValue: true}; - var _false = {keyword: "false", atomValue: false}; - - // Some keywords are treated as regular operators. `in` sometimes - // (when parsing `for`) needs to be tested against specifically, so - // we assign a variable name to it for quick comparing. - - var _in = {keyword: "in", binop: 7, beforeExpr: true}; - - // Map keyword names to token types. - - var keywordTypes = {"break": _break, "case": _case, "catch": _catch, - "continue": _continue, "debugger": _debugger, "default": _default, - "do": _do, "else": _else, "finally": _finally, "for": _for, - "function": _function, "if": _if, "return": _return, "switch": _switch, - "throw": _throw, "try": _try, "var": _var, "while": _while, "with": _with, - "null": _null, "true": _true, "false": _false, "new": _new, "in": _in, - "instanceof": {keyword: "instanceof", binop: 7, beforeExpr: true}, "this": _this, - "typeof": {keyword: "typeof", prefix: true, beforeExpr: true}, - "void": {keyword: "void", prefix: true, beforeExpr: true}, - "delete": {keyword: "delete", prefix: true, beforeExpr: true}}; - - // Punctuation token types. Again, the `type` property is purely for debugging. - - var _bracketL = {type: "[", beforeExpr: true}, _bracketR = {type: "]"}, _braceL = {type: "{", beforeExpr: true}; - var _braceR = {type: "}"}, _parenL = {type: "(", beforeExpr: true}, _parenR = {type: ")"}; - var _comma = {type: ",", beforeExpr: true}, _semi = {type: ";", beforeExpr: true}; - var _colon = {type: ":", beforeExpr: true}, _dot = {type: "."}, _question = {type: "?", beforeExpr: true}; - - // Operators. These carry several kinds of properties to help the - // parser use them properly (the presence of these properties is - // what categorizes them as operators). - // - // `binop`, when present, specifies that this operator is a binary - // operator, and will refer to its precedence. - // - // `prefix` and `postfix` mark the operator as a prefix or postfix - // unary operator. `isUpdate` specifies that the node produced by - // the operator should be of type UpdateExpression rather than - // simply UnaryExpression (`++` and `--`). - // - // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as - // binary operators with a very low precedence, that should result - // in AssignmentExpression nodes. - - var _slash = {binop: 10, beforeExpr: true}, _eq = {isAssign: true, beforeExpr: true}; - var _assign = {isAssign: true, beforeExpr: true}, _plusmin = {binop: 9, prefix: true, beforeExpr: true}; - var _incdec = {postfix: true, prefix: true, isUpdate: true}, _prefix = {prefix: true, beforeExpr: true}; - var _bin1 = {binop: 1, beforeExpr: true}, _bin2 = {binop: 2, beforeExpr: true}; - var _bin3 = {binop: 3, beforeExpr: true}, _bin4 = {binop: 4, beforeExpr: true}; - var _bin5 = {binop: 5, beforeExpr: true}, _bin6 = {binop: 6, beforeExpr: true}; - var _bin7 = {binop: 7, beforeExpr: true}, _bin8 = {binop: 8, beforeExpr: true}; - var _bin10 = {binop: 10, beforeExpr: true}; - - // Provide access to the token types for external users of the - // tokenizer. - - exports.tokTypes = {bracketL: _bracketL, bracketR: _bracketR, braceL: _braceL, braceR: _braceR, - parenL: _parenL, parenR: _parenR, comma: _comma, semi: _semi, colon: _colon, - dot: _dot, question: _question, slash: _slash, eq: _eq, name: _name, eof: _eof, - num: _num, regexp: _regexp, string: _string}; - for (var kw in keywordTypes) exports.tokTypes[kw] = keywordTypes[kw]; - - // This is a trick taken from Esprima. It turns out that, on - // non-Chrome browsers, to check whether a string is in a set, a - // predicate containing a big ugly `switch` statement is faster than - // a regular expression, and on Chrome the two are about on par. - // This function uses `eval` (non-lexical) to produce such a - // predicate from a space-separated string of words. - // - // It starts by sorting the words by length. - - function makePredicate(words) { - words = words.split(" "); - var f = "", cats = []; - out: for (var i = 0; i < words.length; ++i) { - for (var j = 0; j < cats.length; ++j) - if (cats[j][0].length == words[i].length) { - cats[j].push(words[i]); - continue out; - } - cats.push([words[i]]); - } - function compareTo(arr) { - if (arr.length == 1) return f += "return str === " + JSON.stringify(arr[0]) + ";"; - f += "switch(str){"; - for (var i = 0; i < arr.length; ++i) f += "case " + JSON.stringify(arr[i]) + ":"; - f += "return true}return false;"; - } - - // When there are more than three length categories, an outer - // switch first dispatches on the lengths, to save on comparisons. - - if (cats.length > 3) { - cats.sort(function(a, b) {return b.length - a.length;}); - f += "switch(str.length){"; - for (var i = 0; i < cats.length; ++i) { - var cat = cats[i]; - f += "case " + cat[0].length + ":"; - compareTo(cat); - } - f += "}"; - - // Otherwise, simply generate a flat `switch` statement. - - } else { - compareTo(words); - } - return new Function("str", f); - } - - // The ECMAScript 3 reserved word list. - - var isReservedWord3 = makePredicate("abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile"); - - // ECMAScript 5 reserved words. - - var isReservedWord5 = makePredicate("class enum extends super const export import"); - - // The additional reserved words in strict mode. - - var isStrictReservedWord = makePredicate("implements interface let package private protected public static yield"); - - // The forbidden variable names in strict mode. - - var isStrictBadIdWord = makePredicate("eval arguments"); - - // And the keywords. - - var isKeyword = makePredicate("break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this"); - - // ## Character categories - - // Big ugly regular expressions that match characters in the - // whitespace, identifier, and identifier-start categories. These - // are only applied when a character is found to actually have a - // code point above 128. - - var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]/; - var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; - var nonASCIIidentifierChars = "\u0371-\u0374\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u0620-\u0649\u0672-\u06d3\u06e7-\u06e8\u06fb-\u06fc\u0730-\u074a\u0800-\u0814\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0840-\u0857\u08e4-\u08fe\u0900-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962-\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09d7\u09df-\u09e0\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2-\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b5f-\u0b60\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62-\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2-\u0ce3\u0ce6-\u0cef\u0d02\u0d03\u0d46-\u0d48\u0d57\u0d62-\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e34-\u0e3a\u0e40-\u0e45\u0e50-\u0e59\u0eb4-\u0eb9\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f41-\u0f47\u0f71-\u0f84\u0f86-\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u1029\u1040-\u1049\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u170e-\u1710\u1720-\u1730\u1740-\u1750\u1772\u1773\u1780-\u17b2\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u1920-\u192b\u1930-\u193b\u1951-\u196d\u19b0-\u19c0\u19c8-\u19c9\u19d0-\u19d9\u1a00-\u1a15\u1a20-\u1a53\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1b46-\u1b4b\u1b50-\u1b59\u1b6b-\u1b73\u1bb0-\u1bb9\u1be6-\u1bf3\u1c00-\u1c22\u1c40-\u1c49\u1c5b-\u1c7d\u1cd0-\u1cd2\u1d00-\u1dbe\u1e01-\u1f15\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2d81-\u2d96\u2de0-\u2dff\u3021-\u3028\u3099\u309a\ua640-\ua66d\ua674-\ua67d\ua69f\ua6f0-\ua6f1\ua7f8-\ua800\ua806\ua80b\ua823-\ua827\ua880-\ua881\ua8b4-\ua8c4\ua8d0-\ua8d9\ua8f3-\ua8f7\ua900-\ua909\ua926-\ua92d\ua930-\ua945\ua980-\ua983\ua9b3-\ua9c0\uaa00-\uaa27\uaa40-\uaa41\uaa4c-\uaa4d\uaa50-\uaa59\uaa7b\uaae0-\uaae9\uaaf2-\uaaf3\uabc0-\uabe1\uabec\uabed\uabf0-\uabf9\ufb20-\ufb28\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"; - var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); - var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); - - // Whether a single character denotes a newline. - - var newline = /[\n\r\u2028\u2029]/; - - // Matches a whole line break (where CRLF is considered a single - // line break). Used to count lines. - - var lineBreak = /\r\n|[\n\r\u2028\u2029]/g; - - // Test whether a given character code starts an identifier. - - function isIdentifierStart(code) { - if (code < 65) return code === 36; - if (code < 91) return true; - if (code < 97) return code === 95; - if (code < 123)return true; - return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)); - } - - // Test whether a given character is part of an identifier. - - function isIdentifierChar(code) { - if (code < 48) return code === 36; - if (code < 58) return true; - if (code < 65) return false; - if (code < 91) return true; - if (code < 97) return code === 95; - if (code < 123)return true; - return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)); - } - - // ## Tokenizer - - // These are used when `options.locations` is on, for the - // `tokStartLoc` and `tokEndLoc` properties. - - function line_loc_t() { - this.line = tokCurLine; - this.column = tokPos - tokLineStart; - } - - // Reset the token state. Used at the start of a parse. - - function initTokenState() { - tokCurLine = 1; - tokPos = tokLineStart = 0; - tokRegexpAllowed = true; - skipSpace(); - } - - // Called at the end of every token. Sets `tokEnd`, `tokVal`, and - // `tokRegexpAllowed`, and skips the space after the token, so that - // the next one's `tokStart` will point at the right position. - - function finishToken(type, val) { - tokEnd = tokPos; - if (options.locations) tokEndLoc = new line_loc_t; - tokType = type; - skipSpace(); - tokVal = val; - tokRegexpAllowed = type.beforeExpr; - } - - function skipBlockComment() { - var startLoc = options.onComment && options.locations && new line_loc_t; - var start = tokPos, end = input.indexOf("*/", tokPos += 2); - if (end === -1) raise(tokPos - 2, "Unterminated comment"); - tokPos = end + 2; - if (options.locations) { - lineBreak.lastIndex = start; - var match; - while ((match = lineBreak.exec(input)) && match.index < tokPos) { - ++tokCurLine; - tokLineStart = match.index + match[0].length; - } - } - if (options.onComment) - options.onComment(true, input.slice(start + 2, end), start, tokPos, - startLoc, options.locations && new line_loc_t); - } - - function skipLineComment() { - var start = tokPos; - var startLoc = options.onComment && options.locations && new line_loc_t; - var ch = input.charCodeAt(tokPos+=2); - while (tokPos < inputLen && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8329) { - ++tokPos; - ch = input.charCodeAt(tokPos); - } - if (options.onComment) - options.onComment(false, input.slice(start + 2, tokPos), start, tokPos, - startLoc, options.locations && new line_loc_t); - } - - // Called at the start of the parse and after every token. Skips - // whitespace and comments, and. - - function skipSpace() { - while (tokPos < inputLen) { - var ch = input.charCodeAt(tokPos); - if (ch === 32) { // ' ' - ++tokPos; - } else if(ch === 13) { - ++tokPos; - var next = input.charCodeAt(tokPos); - if(next === 10) { - ++tokPos; - } - if(options.locations) { - ++tokCurLine; - tokLineStart = tokPos; - } - } else if (ch === 10) { - ++tokPos; - ++tokCurLine; - tokLineStart = tokPos; - } else if(ch < 14 && ch > 8) { - ++tokPos; - } else if (ch === 47) { // '/' - var next = input.charCodeAt(tokPos+1); - if (next === 42) { // '*' - skipBlockComment(); - } else if (next === 47) { // '/' - skipLineComment(); - } else break; - } else if ((ch < 14 && ch > 8) || ch === 32 || ch === 160) { // ' ', '\xa0' - ++tokPos; - } else if (ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) { - ++tokPos; - } else { - break; - } - } - } - - // ### Token reading - - // This is the function that is called to fetch the next token. It - // is somewhat obscure, because it works in character codes rather - // than characters, and because operator parsing has been inlined - // into it. - // - // All in the name of speed. - // - // The `forceRegexp` parameter is used in the one case where the - // `tokRegexpAllowed` trick does not work. See `parseStatement`. - - function readToken_dot() { - var next = input.charCodeAt(tokPos+1); - if (next >= 48 && next <= 57) return readNumber(true); - ++tokPos; - return finishToken(_dot); - } - - function readToken_slash() { // '/' - var next = input.charCodeAt(tokPos+1); - if (tokRegexpAllowed) {++tokPos; return readRegexp();} - if (next === 61) return finishOp(_assign, 2); - return finishOp(_slash, 1); - } - - function readToken_mult_modulo() { // '%*' - var next = input.charCodeAt(tokPos+1); - if (next === 61) return finishOp(_assign, 2); - return finishOp(_bin10, 1); - } - - function readToken_pipe_amp(code) { // '|&' - var next = input.charCodeAt(tokPos+1); - if (next === code) return finishOp(code === 124 ? _bin1 : _bin2, 2); - if (next === 61) return finishOp(_assign, 2); - return finishOp(code === 124 ? _bin3 : _bin5, 1); - } - - function readToken_caret() { // '^' - var next = input.charCodeAt(tokPos+1); - if (next === 61) return finishOp(_assign, 2); - return finishOp(_bin4, 1); - } - - function readToken_plus_min(code) { // '+-' - var next = input.charCodeAt(tokPos+1); - if (next === code) return finishOp(_incdec, 2); - if (next === 61) return finishOp(_assign, 2); - return finishOp(_plusmin, 1); - } - - function readToken_lt_gt(code) { // '<>' - var next = input.charCodeAt(tokPos+1); - var size = 1; - if (next === code) { - size = code === 62 && input.charCodeAt(tokPos+2) === 62 ? 3 : 2; - if (input.charCodeAt(tokPos + size) === 61) return finishOp(_assign, size + 1); - return finishOp(_bin8, size); - } - if (next === 61) - size = input.charCodeAt(tokPos+2) === 61 ? 3 : 2; - return finishOp(_bin7, size); - } - - function readToken_eq_excl(code) { // '=!' - var next = input.charCodeAt(tokPos+1); - if (next === 61) return finishOp(_bin6, input.charCodeAt(tokPos+2) === 61 ? 3 : 2); - return finishOp(code === 61 ? _eq : _prefix, 1); - } - - function getTokenFromCode(code) { - switch(code) { - // The interpretation of a dot depends on whether it is followed - // by a digit. - case 46: // '.' - return readToken_dot(); - - // Punctuation tokens. - case 40: ++tokPos; return finishToken(_parenL); - case 41: ++tokPos; return finishToken(_parenR); - case 59: ++tokPos; return finishToken(_semi); - case 44: ++tokPos; return finishToken(_comma); - case 91: ++tokPos; return finishToken(_bracketL); - case 93: ++tokPos; return finishToken(_bracketR); - case 123: ++tokPos; return finishToken(_braceL); - case 125: ++tokPos; return finishToken(_braceR); - case 58: ++tokPos; return finishToken(_colon); - case 63: ++tokPos; return finishToken(_question); - - // '0x' is a hexadecimal number. - case 48: // '0' - var next = input.charCodeAt(tokPos+1); - if (next === 120 || next === 88) return readHexNumber(); - // Anything else beginning with a digit is an integer, octal - // number, or float. - case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: // 1-9 - return readNumber(false); - - // Quotes produce strings. - case 34: case 39: // '"', "'" - return readString(code); - - // Operators are parsed inline in tiny state machines. '=' (61) is - // often referred to. `finishOp` simply skips the amount of - // characters it is given as second argument, and returns a token - // of the type given by its first argument. - - case 47: // '/' - return readToken_slash(code); - - case 37: case 42: // '%*' - return readToken_mult_modulo(); - - case 124: case 38: // '|&' - return readToken_pipe_amp(code); - - case 94: // '^' - return readToken_caret(); - - case 43: case 45: // '+-' - return readToken_plus_min(code); - - case 60: case 62: // '<>' - return readToken_lt_gt(code); - - case 61: case 33: // '=!' - return readToken_eq_excl(code); - - case 126: // '~' - return finishOp(_prefix, 1); - } - - return false; - } - - function readToken(forceRegexp) { - if (!forceRegexp) tokStart = tokPos; - else tokPos = tokStart + 1; - if (options.locations) tokStartLoc = new line_loc_t; - if (forceRegexp) return readRegexp(); - if (tokPos >= inputLen) return finishToken(_eof); - - var code = input.charCodeAt(tokPos); - // Identifier or keyword. '\uXXXX' sequences are allowed in - // identifiers, so '\' also dispatches to that. - if (isIdentifierStart(code) || code === 92 /* '\' */) return readWord(); - - var tok = getTokenFromCode(code); - - if (tok === false) { - // If we are here, we either found a non-ASCII identifier - // character, or something that's entirely disallowed. - var ch = String.fromCharCode(code); - if (ch === "\\" || nonASCIIidentifierStart.test(ch)) return readWord(); - raise(tokPos, "Unexpected character '" + ch + "'"); - } - return tok; - } - - function finishOp(type, size) { - var str = input.slice(tokPos, tokPos + size); - tokPos += size; - finishToken(type, str); - } - - // Parse a regular expression. Some context-awareness is necessary, - // since a '/' inside a '[]' set does not end the expression. - - function readRegexp() { - var content = "", escaped, inClass, start = tokPos; - for (;;) { - if (tokPos >= inputLen) raise(start, "Unterminated regular expression"); - var ch = input.charAt(tokPos); - if (newline.test(ch)) raise(start, "Unterminated regular expression"); - if (!escaped) { - if (ch === "[") inClass = true; - else if (ch === "]" && inClass) inClass = false; - else if (ch === "/" && !inClass) break; - escaped = ch === "\\"; - } else escaped = false; - ++tokPos; - } - var content = input.slice(start, tokPos); - ++tokPos; - // Need to use `readWord1` because '\uXXXX' sequences are allowed - // here (don't ask). - var mods = readWord1(); - if (mods && !/^[gmsiy]*$/.test(mods)) raise(start, "Invalid regexp flag"); - return finishToken(_regexp, new RegExp(content, mods)); - } - - // Read an integer in the given radix. Return null if zero digits - // were read, the integer value otherwise. When `len` is given, this - // will return `null` unless the integer has exactly `len` digits. - - function readInt(radix, len) { - var start = tokPos, total = 0; - for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) { - var code = input.charCodeAt(tokPos), val; - if (code >= 97) val = code - 97 + 10; // a - else if (code >= 65) val = code - 65 + 10; // A - else if (code >= 48 && code <= 57) val = code - 48; // 0-9 - else val = Infinity; - if (val >= radix) break; - ++tokPos; - total = total * radix + val; - } - if (tokPos === start || len != null && tokPos - start !== len) return null; - - return total; - } - - function readHexNumber() { - tokPos += 2; // 0x - var val = readInt(16); - if (val == null) raise(tokStart + 2, "Expected hexadecimal number"); - if (isIdentifierStart(input.charCodeAt(tokPos))) raise(tokPos, "Identifier directly after number"); - return finishToken(_num, val); - } - - // Read an integer, octal integer, or floating-point number. - - function readNumber(startsWithDot) { - var start = tokPos, isFloat = false, octal = input.charCodeAt(tokPos) === 48; - if (!startsWithDot && readInt(10) === null) raise(start, "Invalid number"); - if (input.charCodeAt(tokPos) === 46) { - ++tokPos; - readInt(10); - isFloat = true; - } - var next = input.charCodeAt(tokPos); - if (next === 69 || next === 101) { // 'eE' - next = input.charCodeAt(++tokPos); - if (next === 43 || next === 45) ++tokPos; // '+-' - if (readInt(10) === null) raise(start, "Invalid number") - isFloat = true; - } - if (isIdentifierStart(input.charCodeAt(tokPos))) raise(tokPos, "Identifier directly after number"); - - var str = input.slice(start, tokPos), val; - if (isFloat) val = parseFloat(str); - else if (!octal || str.length === 1) val = parseInt(str, 10); - else if (/[89]/.test(str) || strict) raise(start, "Invalid number"); - else val = parseInt(str, 8); - return finishToken(_num, val); - } - - // Read a string value, interpreting backslash-escapes. - - function readString(quote) { - tokPos++; - var out = ""; - for (;;) { - if (tokPos >= inputLen) raise(tokStart, "Unterminated string constant"); - var ch = input.charCodeAt(tokPos); - if (ch === quote) { - ++tokPos; - return finishToken(_string, out); - } - if (ch === 92) { // '\' - ch = input.charCodeAt(++tokPos); - var octal = /^[0-7]+/.exec(input.slice(tokPos, tokPos + 3)); - if (octal) octal = octal[0]; - while (octal && parseInt(octal, 8) > 255) octal = octal.slice(0, octal.length - 1); - if (octal === "0") octal = null; - ++tokPos; - if (octal) { - if (strict) raise(tokPos - 2, "Octal literal in strict mode"); - out += String.fromCharCode(parseInt(octal, 8)); - tokPos += octal.length - 1; - } else { - switch (ch) { - case 110: out += "\n"; break; // 'n' -> '\n' - case 114: out += "\r"; break; // 'r' -> '\r' - case 120: out += String.fromCharCode(readHexChar(2)); break; // 'x' - case 117: out += String.fromCharCode(readHexChar(4)); break; // 'u' - case 85: out += String.fromCharCode(readHexChar(8)); break; // 'U' - case 116: out += "\t"; break; // 't' -> '\t' - case 98: out += "\b"; break; // 'b' -> '\b' - case 118: out += "\u000b"; break; // 'v' -> '\u000b' - case 102: out += "\f"; break; // 'f' -> '\f' - case 48: out += "\0"; break; // 0 -> '\0' - case 13: if (input.charCodeAt(tokPos) === 10) ++tokPos; // '\r\n' - case 10: // ' \n' - if (options.locations) { tokLineStart = tokPos; ++tokCurLine; } - break; - default: out += String.fromCharCode(ch); break; - } - } - } else { - if (ch === 13 || ch === 10 || ch === 8232 || ch === 8329) raise(tokStart, "Unterminated string constant"); - out += String.fromCharCode(ch); // '\' - ++tokPos; - } - } - } - - // Used to read character escape sequences ('\x', '\u', '\U'). - - function readHexChar(len) { - var n = readInt(16, len); - if (n === null) raise(tokStart, "Bad character escape sequence"); - return n; - } - - // Used to signal to callers of `readWord1` whether the word - // contained any escape sequences. This is needed because words with - // escape sequences must not be interpreted as keywords. - - var containsEsc; - - // Read an identifier, and return it as a string. Sets `containsEsc` - // to whether the word contained a '\u' escape. - // - // Only builds up the word character-by-character when it actually - // containeds an escape, as a micro-optimization. - - function readWord1() { - containsEsc = false; - var word, first = true, start = tokPos; - for (;;) { - var ch = input.charCodeAt(tokPos); - if (isIdentifierChar(ch)) { - if (containsEsc) word += input.charAt(tokPos); - ++tokPos; - } else if (ch === 92) { // "\" - if (!containsEsc) word = input.slice(start, tokPos); - containsEsc = true; - if (input.charCodeAt(++tokPos) != 117) // "u" - raise(tokPos, "Expecting Unicode escape sequence \\uXXXX"); - ++tokPos; - var esc = readHexChar(4); - var escStr = String.fromCharCode(esc); - if (!escStr) raise(tokPos - 1, "Invalid Unicode escape"); - if (!(first ? isIdentifierStart(esc) : isIdentifierChar(esc))) - raise(tokPos - 4, "Invalid Unicode escape"); - word += escStr; - } else { - break; - } - first = false; - } - return containsEsc ? word : input.slice(start, tokPos); - } - - // Read an identifier or keyword token. Will check for reserved - // words when necessary. - - function readWord() { - var word = readWord1(); - var type = _name; - if (!containsEsc) { - if (isKeyword(word)) type = keywordTypes[word]; - else if (options.forbidReserved && - (options.ecmaVersion === 3 ? isReservedWord3 : isReservedWord5)(word) || - strict && isStrictReservedWord(word)) - raise(tokStart, "The keyword '" + word + "' is reserved"); - } - return finishToken(type, word); - } - - // ## Parser - - // A recursive descent parser operates by defining functions for all - // syntactic elements, and recursively calling those, each function - // advancing the input stream and returning an AST node. Precedence - // of constructs (for example, the fact that `!x[1]` means `!(x[1])` - // instead of `(!x)[1]` is handled by the fact that the parser - // function that parses unary prefix operators is called first, and - // in turn calls the function that parses `[]` subscripts — that - // way, it'll receive the node for `x[1]` already parsed, and wraps - // *that* in the unary operator node. - // - // Acorn uses an [operator precedence parser][opp] to handle binary - // operator precedence, because it is much more compact than using - // the technique outlined above, which uses different, nesting - // functions to specify precedence, for all of the ten binary - // precedence levels that JavaScript defines. - // - // [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser - - // ### Parser utilities - - // Continue to the next token. - - function next() { - lastStart = tokStart; - lastEnd = tokEnd; - lastEndLoc = tokEndLoc; - readToken(); - } - - // Enter strict mode. Re-reads the next token to please pedantic - // tests ("use strict"; 010; -- should fail). - - function setStrict(strct) { - strict = strct; - tokPos = lastEnd; - while (tokPos < tokLineStart) { - tokLineStart = input.lastIndexOf("\n", tokLineStart - 2) + 1; - --tokCurLine; - } - skipSpace(); - readToken(); - } - - // Start an AST node, attaching a start offset. - - function node_t() { - this.type = null; - this.start = tokStart; - this.end = null; - } - - function node_loc_t() { - this.start = tokStartLoc; - this.end = null; - if (sourceFile !== null) this.source = sourceFile; - } - - function startNode() { - var node = new node_t(); - if (options.locations) - node.loc = new node_loc_t(); - if (options.ranges) - node.range = [tokStart, 0]; - return node; - } - - // Start a node whose start offset information should be based on - // the start of another node. For example, a binary operator node is - // only started after its left-hand side has already been parsed. - - function startNodeFrom(other) { - var node = new node_t(); - node.start = other.start; - if (options.locations) { - node.loc = new node_loc_t(); - node.loc.start = other.loc.start; - } - if (options.ranges) - node.range = [other.range[0], 0]; - - return node; - } - - // Finish an AST node, adding `type` and `end` properties. - - function finishNode(node, type) { - node.type = type; - node.end = lastEnd; - if (options.locations) - node.loc.end = lastEndLoc; - if (options.ranges) - node.range[1] = lastEnd; - return node; - } - - // Test whether a statement node is the string literal `"use strict"`. - - function isUseStrict(stmt) { - return options.ecmaVersion >= 5 && stmt.type === "ExpressionStatement" && - stmt.expression.type === "Literal" && stmt.expression.value === "use strict"; - } - - // Predicate that tests whether the next token is of the given - // type, and if yes, consumes it as a side effect. - - function eat(type) { - if (tokType === type) { - next(); - return true; - } - } - - // Test whether a semicolon can be inserted at the current position. - - function canInsertSemicolon() { - return !options.strictSemicolons && - (tokType === _eof || tokType === _braceR || newline.test(input.slice(lastEnd, tokStart))); - } - - // Consume a semicolon, or, failing that, see if we are allowed to - // pretend that there is a semicolon at this position. - - function semicolon() { - if (!eat(_semi) && !canInsertSemicolon()) unexpected(); - } - - // Expect a token of a given type. If found, consume it, otherwise, - // raise an unexpected token error. - - function expect(type) { - if (tokType === type) next(); - else unexpected(); - } - - // Raise an unexpected token error. - - function unexpected() { - raise(tokStart, "Unexpected token"); - } - - // Verify that a node is an lval — something that can be assigned - // to. - - function checkLVal(expr) { - if (expr.type !== "Identifier" && expr.type !== "MemberExpression") - raise(expr.start, "Assigning to rvalue"); - if (strict && expr.type === "Identifier" && isStrictBadIdWord(expr.name)) - raise(expr.start, "Assigning to " + expr.name + " in strict mode"); - } - - // ### Statement parsing - - // Parse a program. Initializes the parser, reads any number of - // statements, and wraps them in a Program node. Optionally takes a - // `program` argument. If present, the statements will be appended - // to its body instead of creating a new node. - - function parseTopLevel(program) { - lastStart = lastEnd = tokPos; - if (options.locations) lastEndLoc = new line_loc_t; - inFunction = strict = null; - labels = []; - readToken(); - - var node = program || startNode(), first = true; - if (!program) node.body = []; - while (tokType !== _eof) { - var stmt = parseStatement(); - node.body.push(stmt); - if (first && isUseStrict(stmt)) setStrict(true); - first = false; - } - return finishNode(node, "Program"); - } - - var loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"}; - - // Parse a single statement. - // - // If expecting a statement and finding a slash operator, parse a - // regular expression literal. This is to handle cases like - // `if (foo) /blah/.exec(foo);`, where looking at the previous token - // does not help. - - function parseStatement() { - if (tokType === _slash) - readToken(true); - - var starttype = tokType, node = startNode(); - - // Most types of statements are recognized by the keyword they - // start with. Many are trivial to parse, some require a bit of - // complexity. - - switch (starttype) { - case _break: case _continue: - next(); - var isBreak = starttype === _break; - if (eat(_semi) || canInsertSemicolon()) node.label = null; - else if (tokType !== _name) unexpected(); - else { - node.label = parseIdent(); - semicolon(); - } - - // Verify that there is an actual destination to break or - // continue to. - for (var i = 0; i < labels.length; ++i) { - var lab = labels[i]; - if (node.label == null || lab.name === node.label.name) { - if (lab.kind != null && (isBreak || lab.kind === "loop")) break; - if (node.label && isBreak) break; - } - } - if (i === labels.length) raise(node.start, "Unsyntactic " + starttype.keyword); - return finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement"); - - case _debugger: - next(); - semicolon(); - return finishNode(node, "DebuggerStatement"); - - case _do: - next(); - labels.push(loopLabel); - node.body = parseStatement(); - labels.pop(); - expect(_while); - node.test = parseParenExpression(); - semicolon(); - return finishNode(node, "DoWhileStatement"); - - // Disambiguating between a `for` and a `for`/`in` loop is - // non-trivial. Basically, we have to parse the init `var` - // statement or expression, disallowing the `in` operator (see - // the second parameter to `parseExpression`), and then check - // whether the next token is `in`. When there is no init part - // (semicolon immediately after the opening parenthesis), it is - // a regular `for` loop. - - case _for: - next(); - labels.push(loopLabel); - expect(_parenL); - if (tokType === _semi) return parseFor(node, null); - if (tokType === _var) { - var init = startNode(); - next(); - parseVar(init, true); - if (init.declarations.length === 1 && eat(_in)) - return parseForIn(node, init); - return parseFor(node, init); - } - var init = parseExpression(false, true); - if (eat(_in)) {checkLVal(init); return parseForIn(node, init);} - return parseFor(node, init); - - case _function: - next(); - return parseFunction(node, true); - - case _if: - next(); - node.test = parseParenExpression(); - node.consequent = parseStatement(); - node.alternate = eat(_else) ? parseStatement() : null; - return finishNode(node, "IfStatement"); - - case _return: - if (!inFunction) raise(tokStart, "'return' outside of function"); - next(); - - // In `return` (and `break`/`continue`), the keywords with - // optional arguments, we eagerly look for a semicolon or the - // possibility to insert one. - - if (eat(_semi) || canInsertSemicolon()) node.argument = null; - else { node.argument = parseExpression(); semicolon(); } - return finishNode(node, "ReturnStatement"); - - case _switch: - next(); - node.discriminant = parseParenExpression(); - node.cases = []; - expect(_braceL); - labels.push(switchLabel); - - // Statements under must be grouped (by label) in SwitchCase - // nodes. `cur` is used to keep the node that we are currently - // adding statements to. - - for (var cur, sawDefault; tokType != _braceR;) { - if (tokType === _case || tokType === _default) { - var isCase = tokType === _case; - if (cur) finishNode(cur, "SwitchCase"); - node.cases.push(cur = startNode()); - cur.consequent = []; - next(); - if (isCase) cur.test = parseExpression(); - else { - if (sawDefault) raise(lastStart, "Multiple default clauses"); sawDefault = true; - cur.test = null; - } - expect(_colon); - } else { - if (!cur) unexpected(); - cur.consequent.push(parseStatement()); - } - } - if (cur) finishNode(cur, "SwitchCase"); - next(); // Closing brace - labels.pop(); - return finishNode(node, "SwitchStatement"); - - case _throw: - next(); - if (newline.test(input.slice(lastEnd, tokStart))) - raise(lastEnd, "Illegal newline after throw"); - node.argument = parseExpression(); - semicolon(); - return finishNode(node, "ThrowStatement"); - - case _try: - next(); - node.block = parseBlock(); - node.handler = null; - if (tokType === _catch) { - var clause = startNode(); - next(); - expect(_parenL); - clause.param = parseIdent(); - if (strict && isStrictBadIdWord(clause.param.name)) - raise(clause.param.start, "Binding " + clause.param.name + " in strict mode"); - expect(_parenR); - clause.guard = null; - clause.body = parseBlock(); - node.handler = finishNode(clause, "CatchClause"); - } - node.finalizer = eat(_finally) ? parseBlock() : null; - if (!node.handler && !node.finalizer) - raise(node.start, "Missing catch or finally clause"); - return finishNode(node, "TryStatement"); - - case _var: - next(); - node = parseVar(node); - semicolon(); - return node; - - case _while: - next(); - node.test = parseParenExpression(); - labels.push(loopLabel); - node.body = parseStatement(); - labels.pop(); - return finishNode(node, "WhileStatement"); - - case _with: - if (strict) raise(tokStart, "'with' in strict mode"); - next(); - node.object = parseParenExpression(); - node.body = parseStatement(); - return finishNode(node, "WithStatement"); - - case _braceL: - return parseBlock(); - - case _semi: - next(); - return finishNode(node, "EmptyStatement"); - - // If the statement does not start with a statement keyword or a - // brace, it's an ExpressionStatement or LabeledStatement. We - // simply start parsing an expression, and afterwards, if the - // next token is a colon and the expression was a simple - // Identifier node, we switch to interpreting it as a label. - - default: - var maybeName = tokVal, expr = parseExpression(); - if (starttype === _name && expr.type === "Identifier" && eat(_colon)) { - for (var i = 0; i < labels.length; ++i) - if (labels[i].name === maybeName) raise(expr.start, "Label '" + maybeName + "' is already declared"); - var kind = tokType.isLoop ? "loop" : tokType === _switch ? "switch" : null; - labels.push({name: maybeName, kind: kind}); - node.body = parseStatement(); - labels.pop(); - node.label = expr; - return finishNode(node, "LabeledStatement"); - } else { - node.expression = expr; - semicolon(); - return finishNode(node, "ExpressionStatement"); - } - } - } - - // Used for constructs like `switch` and `if` that insist on - // parentheses around their expression. - - function parseParenExpression() { - expect(_parenL); - var val = parseExpression(); - expect(_parenR); - return val; - } - - // Parse a semicolon-enclosed block of statements, handling `"use - // strict"` declarations when `allowStrict` is true (used for - // function bodies). - - function parseBlock(allowStrict) { - var node = startNode(), first = true, strict = false, oldStrict; - node.body = []; - expect(_braceL); - while (!eat(_braceR)) { - var stmt = parseStatement(); - node.body.push(stmt); - if (first && isUseStrict(stmt)) { - oldStrict = strict; - setStrict(strict = true); - } - first = false - } - if (strict && !oldStrict) setStrict(false); - return finishNode(node, "BlockStatement"); - } - - // Parse a regular `for` loop. The disambiguation code in - // `parseStatement` will already have parsed the init statement or - // expression. - - function parseFor(node, init) { - node.init = init; - expect(_semi); - node.test = tokType === _semi ? null : parseExpression(); - expect(_semi); - node.update = tokType === _parenR ? null : parseExpression(); - expect(_parenR); - node.body = parseStatement(); - labels.pop(); - return finishNode(node, "ForStatement"); - } - - // Parse a `for`/`in` loop. - - function parseForIn(node, init) { - node.left = init; - node.right = parseExpression(); - expect(_parenR); - node.body = parseStatement(); - labels.pop(); - return finishNode(node, "ForInStatement"); - } - - // Parse a list of variable declarations. - - function parseVar(node, noIn) { - node.declarations = []; - node.kind = "var"; - for (;;) { - var decl = startNode(); - decl.id = parseIdent(); - if (strict && isStrictBadIdWord(decl.id.name)) - raise(decl.id.start, "Binding " + decl.id.name + " in strict mode"); - decl.init = eat(_eq) ? parseExpression(true, noIn) : null; - node.declarations.push(finishNode(decl, "VariableDeclarator")); - if (!eat(_comma)) break; - } - return finishNode(node, "VariableDeclaration"); - } - - // ### Expression parsing - - // These nest, from the most general expression type at the top to - // 'atomic', nondivisible expression types at the bottom. Most of - // the functions will simply let the function(s) below them parse, - // and, *if* the syntactic construct they handle is present, wrap - // the AST node that the inner parser gave them in another node. - - // Parse a full expression. The arguments are used to forbid comma - // sequences (in argument lists, array literals, or object literals) - // or the `in` operator (in for loops initalization expressions). - - function parseExpression(noComma, noIn) { - var expr = parseMaybeAssign(noIn); - if (!noComma && tokType === _comma) { - var node = startNodeFrom(expr); - node.expressions = [expr]; - while (eat(_comma)) node.expressions.push(parseMaybeAssign(noIn)); - return finishNode(node, "SequenceExpression"); - } - return expr; - } - - // Parse an assignment expression. This includes applications of - // operators like `+=`. - - function parseMaybeAssign(noIn) { - var left = parseMaybeConditional(noIn); - if (tokType.isAssign) { - var node = startNodeFrom(left); - node.operator = tokVal; - node.left = left; - next(); - node.right = parseMaybeAssign(noIn); - checkLVal(left); - return finishNode(node, "AssignmentExpression"); - } - return left; - } - - // Parse a ternary conditional (`?:`) operator. - - function parseMaybeConditional(noIn) { - var expr = parseExprOps(noIn); - if (eat(_question)) { - var node = startNodeFrom(expr); - node.test = expr; - node.consequent = parseExpression(true); - expect(_colon); - node.alternate = parseExpression(true, noIn); - return finishNode(node, "ConditionalExpression"); - } - return expr; - } - - // Start the precedence parser. - - function parseExprOps(noIn) { - return parseExprOp(parseMaybeUnary(noIn), -1, noIn); - } - - // Parse binary operators with the operator precedence parsing - // algorithm. `left` is the left-hand side of the operator. - // `minPrec` provides context that allows the function to stop and - // defer further parser to one of its callers when it encounters an - // operator that has a lower precedence than the set it is parsing. - - function parseExprOp(left, minPrec, noIn) { - var prec = tokType.binop; - if (prec != null && (!noIn || tokType !== _in)) { - if (prec > minPrec) { - var node = startNodeFrom(left); - node.left = left; - node.operator = tokVal; - next(); - node.right = parseExprOp(parseMaybeUnary(noIn), prec, noIn); - var node = finishNode(node, /&&|\|\|/.test(node.operator) ? "LogicalExpression" : "BinaryExpression"); - return parseExprOp(node, minPrec, noIn); - } - } - return left; - } - - // Parse unary operators, both prefix and postfix. - - function parseMaybeUnary(noIn) { - if (tokType.prefix) { - var node = startNode(), update = tokType.isUpdate; - node.operator = tokVal; - node.prefix = true; - next(); - node.argument = parseMaybeUnary(noIn); - if (update) checkLVal(node.argument); - else if (strict && node.operator === "delete" && - node.argument.type === "Identifier") - raise(node.start, "Deleting local variable in strict mode"); - return finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); - } - var expr = parseExprSubscripts(); - while (tokType.postfix && !canInsertSemicolon()) { - var node = startNodeFrom(expr); - node.operator = tokVal; - node.prefix = false; - node.argument = expr; - checkLVal(expr); - next(); - expr = finishNode(node, "UpdateExpression"); - } - return expr; - } - - // Parse call, dot, and `[]`-subscript expressions. - - function parseExprSubscripts() { - return parseSubscripts(parseExprAtom()); - } - - function parseSubscripts(base, noCalls) { - if (eat(_dot)) { - var node = startNodeFrom(base); - node.object = base; - node.property = parseIdent(true); - node.computed = false; - return parseSubscripts(finishNode(node, "MemberExpression"), noCalls); - } else if (eat(_bracketL)) { - var node = startNodeFrom(base); - node.object = base; - node.property = parseExpression(); - node.computed = true; - expect(_bracketR); - return parseSubscripts(finishNode(node, "MemberExpression"), noCalls); - } else if (!noCalls && eat(_parenL)) { - var node = startNodeFrom(base); - node.callee = base; - node.arguments = parseExprList(_parenR, false); - return parseSubscripts(finishNode(node, "CallExpression"), noCalls); - } else return base; - } - - // Parse an atomic expression — either a single token that is an - // expression, an expression started by a keyword like `function` or - // `new`, or an expression wrapped in punctuation like `()`, `[]`, - // or `{}`. - - function parseExprAtom() { - switch (tokType) { - case _this: - var node = startNode(); - next(); - return finishNode(node, "ThisExpression"); - case _name: - return parseIdent(); - case _num: case _string: case _regexp: - var node = startNode(); - node.value = tokVal; - node.raw = input.slice(tokStart, tokEnd); - next(); - return finishNode(node, "Literal"); - - case _null: case _true: case _false: - var node = startNode(); - node.value = tokType.atomValue; - node.raw = tokType.keyword - next(); - return finishNode(node, "Literal"); - - case _parenL: - var tokStartLoc1 = tokStartLoc, tokStart1 = tokStart; - next(); - var val = parseExpression(); - val.start = tokStart1; - val.end = tokEnd; - if (options.locations) { - val.loc.start = tokStartLoc1; - val.loc.end = tokEndLoc; - } - if (options.ranges) - val.range = [tokStart1, tokEnd]; - expect(_parenR); - return val; - - case _bracketL: - var node = startNode(); - next(); - node.elements = parseExprList(_bracketR, true, true); - return finishNode(node, "ArrayExpression"); - - case _braceL: - return parseObj(); - - case _function: - var node = startNode(); - next(); - return parseFunction(node, false); - - case _new: - return parseNew(); - - default: - unexpected(); - } - } - - // New's precedence is slightly tricky. It must allow its argument - // to be a `[]` or dot subscript expression, but not a call — at - // least, not without wrapping it in parentheses. Thus, it uses the - - function parseNew() { - var node = startNode(); - next(); - node.callee = parseSubscripts(parseExprAtom(), true); - if (eat(_parenL)) node.arguments = parseExprList(_parenR, false); - else node.arguments = []; - return finishNode(node, "NewExpression"); - } - - // Parse an object literal. - - function parseObj() { - var node = startNode(), first = true, sawGetSet = false; - node.properties = []; - next(); - while (!eat(_braceR)) { - if (!first) { - expect(_comma); - if (options.allowTrailingCommas && eat(_braceR)) break; - } else first = false; - - var prop = {key: parsePropertyName()}, isGetSet = false, kind; - if (eat(_colon)) { - prop.value = parseExpression(true); - kind = prop.kind = "init"; - } else if (options.ecmaVersion >= 5 && prop.key.type === "Identifier" && - (prop.key.name === "get" || prop.key.name === "set")) { - isGetSet = sawGetSet = true; - kind = prop.kind = prop.key.name; - prop.key = parsePropertyName(); - if (tokType !== _parenL) unexpected(); - prop.value = parseFunction(startNode(), false); - } else unexpected(); - - // getters and setters are not allowed to clash — either with - // each other or with an init property — and in strict mode, - // init properties are also not allowed to be repeated. - - if (prop.key.type === "Identifier" && (strict || sawGetSet)) { - for (var i = 0; i < node.properties.length; ++i) { - var other = node.properties[i]; - if (other.key.name === prop.key.name) { - var conflict = kind == other.kind || isGetSet && other.kind === "init" || - kind === "init" && (other.kind === "get" || other.kind === "set"); - if (conflict && !strict && kind === "init" && other.kind === "init") conflict = false; - if (conflict) raise(prop.key.start, "Redefinition of property"); - } - } - } - node.properties.push(prop); - } - return finishNode(node, "ObjectExpression"); - } - - function parsePropertyName() { - if (tokType === _num || tokType === _string) return parseExprAtom(); - return parseIdent(true); - } - - // Parse a function declaration or literal (depending on the - // `isStatement` parameter). - - function parseFunction(node, isStatement) { - if (tokType === _name) node.id = parseIdent(); - else if (isStatement) unexpected(); - else node.id = null; - node.params = []; - var first = true; - expect(_parenL); - while (!eat(_parenR)) { - if (!first) expect(_comma); else first = false; - node.params.push(parseIdent()); - } - - // Start a new scope with regard to labels and the `inFunction` - // flag (restore them to their old value afterwards). - var oldInFunc = inFunction, oldLabels = labels; - inFunction = true; labels = []; - node.body = parseBlock(true); - inFunction = oldInFunc; labels = oldLabels; - - // If this is a strict mode function, verify that argument names - // are not repeated, and it does not try to bind the words `eval` - // or `arguments`. - if (strict || node.body.body.length && isUseStrict(node.body.body[0])) { - for (var i = node.id ? -1 : 0; i < node.params.length; ++i) { - var id = i < 0 ? node.id : node.params[i]; - if (isStrictReservedWord(id.name) || isStrictBadIdWord(id.name)) - raise(id.start, "Defining '" + id.name + "' in strict mode"); - if (i >= 0) for (var j = 0; j < i; ++j) if (id.name === node.params[j].name) - raise(id.start, "Argument name clash in strict mode"); - } - } - - return finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression"); - } - - // Parses a comma-separated list of expressions, and returns them as - // an array. `close` is the token type that ends the list, and - // `allowEmpty` can be turned on to allow subsequent commas with - // nothing in between them to be parsed as `null` (which is needed - // for array literals). - - function parseExprList(close, allowTrailingComma, allowEmpty) { - var elts = [], first = true; - while (!eat(close)) { - if (!first) { - expect(_comma); - if (allowTrailingComma && options.allowTrailingCommas && eat(close)) break; - } else first = false; - - if (allowEmpty && tokType === _comma) elts.push(null); - else elts.push(parseExpression(true)); - } - return elts; - } - - // Parse the next token as an identifier. If `liberal` is true (used - // when parsing properties), it will also convert keywords into - // identifiers. - - function parseIdent(liberal) { - var node = startNode(); - node.name = tokType === _name ? tokVal : (liberal && !options.forbidReserved && tokType.keyword) || unexpected(); - next(); - return finishNode(node, "Identifier"); - } - -}); - -(function (global) { - if (typeof window === "undefined") { - window = this; - } - //$data = window["$data"] || (window["$data"] = {}); - $data = window["$data"] || (window["$data"] = (function _data_handler() { - //console.log("@@@@", this); - if (this instanceof _data_handler) { - //console.log( - var type = _data_handler["implementation"].apply(this, arguments); - return new type(arguments[1]); - } else { - - return _data_handler["implementation"].apply(this, arguments) - } - })); -})(this); - -if (typeof console === 'undefined') { - console = { - warn: function () { }, - error: function () { }, - log: function () { }, - dir: function () { }, - time: function () { }, - timeEnd: function () { } - }; -} - -if (!console.warn) console.warn = function () { }; -if (!console.error) console.error = function () { }; - -(function ($data) { - /// - /// Collection of JayData services - /// - $data.__namespace = true; - $data.version = "JayData 1.3.6"; - $data.versionNumber = "1.3.6"; - $data.root = {}; - $data.Acorn = $data.Acorn || (typeof acorn == 'object' ? acorn : undefined); - $data.Esprima = $data.Esprima || (typeof esprima == 'object' ? esprima : undefined); - -})($data); - -// Do not remove this block, it is used by jsdoc -/** - @name $data.Base - @class base class -*/ -Exception = function(message, name, data) { - Error.call(this); - if (Error.captureStackTrace) - Error.captureStackTrace(this, this.constructor); - - this.name = name || "Exception"; - this.message = message; - this.data = data; - - //this.toString = function() { return JSON.stringify(this); }; - -} - -Exception.prototype.__proto__ = Error.prototype; - -Exception.prototype._getStackTrace = function () { - var callstack = []; - var isCallstackPopulated = false; - // unreachable code - //return; - /*try { - i.dont.exist += 0; - } - catch (e) { - if (e.stack) { // Firefox, Chrome - var lines = e.stack.split('\n'); - for (var i = 0, len = lines.length; i < len; i++) { - //if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) { - if (lines[i].indexOf(" at ") >= 0) - callstack.push(lines[i]); - } - //Remove call to printStackTrace() - callstack.shift(); - //TODO: Remove call to new Exception( chain - //callstack.shift(); - isCallstackPopulated = true; - } - else if (window.opera && e.message) { //Opera - var lines = e.message.split('\n'); - for (var i = 0, len = lines.length; i < len; i++) { - if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) { - var entry = lines[i]; - //Append next line also since it has the file info - if (lines[i + 1]) { - entry += ' at ' + lines[i + 1]; - i++; - } - callstack.push(entry); - } - } - //Remove call to printStackTrace() - callstack.shift(); - //TODO: Remove call to new Exception( chain - //callstack.shift(); - isCallstackPopulated = true; - } - } - - //if (!isCallstackPopulated) { //IE and Safari - // var currentFunction = arguments.callee.caller; - // while (currentFunction) { - // var fn = currentFunction.toString(); - // var fname = fn.substring(fn.indexOf("function") + 8, fn.indexOf('(')) || 'anonymous'; - // callstack.push(fname); - // if (currentFunction == currentFunction.caller) { - // Guard.raise("Infinite loop"); - // } - // currentFunction = currentFunction.caller; - // } - //} - return callstack.join("\n\r"); */ -}; -Guard = {}; -Guard.requireValue = function (name, value) { - if (typeof value === 'undefined' || value === null) { - Guard.raise(name + " requires a value other than undefined or null"); - } -}; - -Guard.requireType = function (name, value, typeOrTypes) { - var types = typeOrTypes instanceof Array ? typeOrTypes : [typeOrTypes]; - return types.some(function (item) { - switch (typeof item) { - case "string": - return typeof value === item; - case "function": - return value instanceof item; - default: - Guard.raise("Unknown type format : " + typeof item + " for: "+ name); - } - }); -}; - -Guard.raise = function(exception){ - if (typeof intellisense === 'undefined') { - if (exception instanceof Exception){ - console.error(exception.name + ':', exception.message + '\n', exception); - }else{ - console.error(exception); - } - throw exception; - } -}; - -Object.isNullOrUndefined = function (value) { - return value === undefined || value === null; -}; -(function ObjectMethodsForPreHTML5Browsers() { - - if (!Object.getOwnPropertyNames){ - Object.getOwnPropertyNames = function(o){ - var names = []; - - for (var i in o){ - if (o.hasOwnProperty(i)) names.push(i); - } - - return names; - }; - } - - if (!Object.create) { - Object.create = function (o) { - if (arguments.length > 1) { - Guard.raise(new Error('Object.create implementation only accepts the first parameter.')); - } - function F() { } - F.prototype = o; - return new F(); - }; - } - - if (!Object.keys) { - var hasOwnProperty = Object.prototype.hasOwnProperty, - hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'), - dontEnums = ['toString', - 'toLocaleString', - 'valueOf', - 'hasOwnProperty', - 'isPrototypeOf', - 'propertyIsEnumerable', - 'constructor'], - dontEnumsLength = dontEnums.length; - - Object.keys = function (obj) { - - ///Refactor to Assert.IsObjectOrFunction - if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) Guard.raise(new TypeError('Object.keys called on non-object')); - - var result = []; - - for (var prop in obj) { - if (hasOwnProperty.call(obj, prop)) { - result.push(prop); - } - } - - if (hasDontEnumBug) { - for (var i = 0; i < dontEnumsLength; i++) { - if (hasOwnProperty.call(obj, dontEnums[i])) { - result.push(dontEnums[i]); - } - } - } - - return result; - }; - } - - if (!Object.defineProperty) { - Object.defineProperty = function (obj, propName, propDef) { - obj[propName] = propDef.value || {}; - }; - } - - if (!Object.defineProperties) { - Object.defineProperties = function (obj, defines) { - for (var i in defines) { - if(defines.hasOwnProperty(i)) - obj[i] = defines[i].value || {}; - } - }; - } - - if (!Array.prototype.forEach) { - Array.prototype.forEach = function (handler, thisArg) { - for (var i = 0, l = this.length; i < l; i++) { - if (thisArg) { handler.call(thisArg, this[i], i, this); } - else { handler(this[i], i, this); }; - }; - }; - }; - - if (!Array.prototype.filter) { - Array.prototype.filter = function (handler, thisArg) { - var result = []; - for (var i = 0, l = this.length; i < l; i++) { - var r = thisArg ? - handler.call(thisArg, this[i], i, this) : - handler(this[i], i, this); - if (r === true) { - result.push(this[i]); - } - } - return result; - }; - } - - if (!Array.prototype.map) { - Array.prototype.map = function (handler, thisArg) { - var result = []; - for (var i = 0, l = this.length; i < l; i++) { - var r = thisArg ? - handler.call(thisArg, this[i], i, this) : - handler(this[i], i, this); - result.push(r); - } - return result; - }; - } - - if (!Array.prototype.some) { - Array.prototype.some = function (handler, thisArg) { - for (var i = 0, l = this.length; i < l; i++) { - var r = thisArg ? - handler.call(thisArg, this[i], i, this) : - handler(this[i], i, this); - if (r) { return true; } - - } - return false; - }; - } - - if (!Array.prototype.indexOf) { - Array.prototype.indexOf = function (item, from) { - for (var i = 0, l = this.length; i < l; i++) { - if (this[i] === item) { - return i; - }; - }; - return -1; - }; - } - - if (!String.prototype.trimLeft) { - String.prototype.trimLeft = function () { - return this.replace(/^\s+/, ""); - } - } - - if (!String.prototype.trimRight) { - String.prototype.trimRight = function () { - return this.replace(/\s+$/, ""); - } - } - - if (!Function.prototype.bind) { - Function.prototype.bind = function (oThis) { - if (typeof this !== "function") { - // closest thing possible to the ECMAScript 5 internal IsCallable function - throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); - } - - var aArgs = Array.prototype.slice.call(arguments, 1), - fToBind = this, - fNOP = function () { }, - fBound = function () { - return fToBind.apply(this instanceof fNOP && oThis - ? this - : oThis, - aArgs.concat(Array.prototype.slice.call(arguments))); - }; - - fNOP.prototype = this.prototype; - fBound.prototype = new fNOP(); - - return fBound; - }; - } - - if (typeof Uint8Array == 'undefined'){ - Uint8Array = function(v){ - if (v instanceof Uint8Array) return v; - var self = this; - var buffer = Array.isArray(v) ? v : new Array(v); - this.length = buffer.length; - this.byteLength = this.length; - this.byteOffset = 0; - this.buffer = { byteLength: self.length }; - var getter = function(index){ - return buffer[index]; - }; - var setter = function(index, value){ - buffer[index] = (value | 0) & 0xff; - }; - var makeAccessor = function(i){ - buffer[i] = buffer[i] || 0; - Object.defineProperty(self, i, { - enumerable: true, - configurable: false, - get: function(){ - if (isNaN(+i) || ((i | 0) < 0 || (i | 0) >= self.length)){ - try{ - if (typeof document != 'undefined') document.createTextNode("").splitText(1); - return new RangeError("INDEX_SIZE_ERR"); - }catch(e){ - return e; - } - } - return getter(i); - }, - set: function(v){ - if (isNaN(+i) || ((i | 0) < 0 || (i | 0) >= self.length)){ - try{ - if (typeof document != 'undefined') document.createTextNode("").splitText(1); - return new RangeError("INDEX_SIZE_ERR"); - }catch(e){ - return e; - } - } - setter(i | 0, v); - } - }); - }; - for (var i = 0; i < self.length; i++){ - makeAccessor(i); - } - }; - } - -})(); -(function init($data, global) { - - function il(msg) { - if (typeof intellisense !== 'undefined') { - if (!intellisense.i) { - intellisense.i = 0; - } - intellisense.i = intellisense.i + 1; - intellisense.logMessage(msg + ":" + intellisense.i); - } - } - - function MemberDefinition(memberDefinitionData, definedClass) { - - ///* - ///* - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - ///[false] if false value is stored in initData, otherwise on the object - ///[true] if set to false propertyChange events are not raise and property tracking is disabled - - this.kind = MemberTypes.property; - //this.definedBy = definedClass; - Object.defineProperty(this, 'definedBy', { value: definedClass, enumerable: false, configurable: false, writable: false }); - if (memberDefinitionData) { - if (typeof memberDefinitionData === 'function' || typeof memberDefinitionData.asFunction === 'function') { - this.method = memberDefinitionData; - this.kind = MemberTypes.method; - } else { - this.enumerable = true; - this.configurable = true; - if (typeof memberDefinitionData === "number") { - this.value = memberDefinitionData; - this.type = $data.Number; - this.dataType = $data.Number; - } else if (typeof memberDefinitionData === "string") { - this.value = memberDefinitionData; - this.dataType = $data.String; - this.type = $data.String; - } else { - for (var item in memberDefinitionData) { - if (memberDefinitionData.hasOwnProperty(item)) { - this[item] = memberDefinitionData[item]; - } - } - } - } - if (this.type !== undefined) { - this.dataType = this.dataType || this.type; - } else { - this.type = this.dataType; - } - - this.originalType = this.type; - if (this.elementType !== undefined) { - this.originalElementType = this.elementType; - } - } - } - MemberDefinition.prototype.createPropertyDescriptor = function (classFunction, value) { - /// - var pd = this; - var result = { - enumerable: this.enumerable == undefined ? true : this.enumerable, - configurable: this.configurable == undefined ? true : this.configurable - }; - if (this.set && this.get) { - result.set = this.set; - result.get = this.get; - } else if ("value" in this || value) { - result.value = value || this.value; - //TODO - //result.writable = this.writable; - result.writable = true; - } - else { - result.set = function (value) { this.storeProperty(pd, value); }; - result.get = function () { return this.retrieveProperty(pd); }; - } - return result; - }; - MemberDefinition.prototype.createStorePropertyDescriptor = function (value) { - var pd = this; - return { enumerable: false, writable: true, configurable: pd.configurable, value: value }; - }; - MemberDefinition.prototype.createGetMethod = function () { - var pd = this; - return { - enumerable: false, writable: false, configurable: false, - value: function (callback, tran) { return this.getProperty(pd, callback, tran); } - }; - }; - MemberDefinition.prototype.createSetMethod = function () { - var pd = this; - return { - enumerable: false, writable: false, configurable: false, - value: function (value, callback, tran) { return this.setProperty(pd, value, callback, tran); } - }; - }; - MemberDefinition.translateDefinition = function (memDef, name, classFunction) { - var holder = classFunction; - var memberDefinition; - - if (memDef.type && Container.isTypeRegistered(memDef.type)) { - holder = Container.resolveType(memDef.type); - if (typeof holder.translateDefinition === 'function') { - memberDefinition = holder.translateDefinition.apply(holder, arguments); - memberDefinition.name = memberDefinition.name || name; - } else { - holder = classFunction; - } - } - - - if (!(memberDefinition instanceof MemberDefinition)) { - memberDefinition = new MemberDefinition(memberDefinition || memDef, holder); - memberDefinition.name = name; - } - classFunction.resolverThunks = classFunction.resolverThunks || []; - classFunction.childResolverThunks = classFunction.childResolverThunks || []; - - - var t = memberDefinition.type; - var et = memberDefinition.elementType; - - function addChildThunk(referencedType) { - if (referencedType && referencedType.isAssignableTo && $data.Entity && referencedType.isAssignableTo($data.Entity)) { - classFunction.childResolverThunks.push(function () { - if (referencedType.resolveForwardDeclarations) { - referencedType.resolveForwardDeclarations(); - } - }); - } - } - - addChildThunk(t); - addChildThunk(et); - - if ("string" === typeof t) { - if ("@" === t[0]) { - memberDefinition.type = t.substr(1); - memberDefinition.dataType = t.substr(1); - } else { - //forward declared types get this callback when type is registered - classFunction.resolverThunks.push(function () { - var rt = classFunction.container.resolveType(t); - addChildThunk(rt); - memberDefinition.type = rt; - memberDefinition.dataType = rt; - }); - } - } - - if (et) { - if ("string" === typeof et) { - if ("@" === et[0]) { - memberDefinition.elementType = et.substr(1); - } else { - //forward declared types get this callback when type is registered - classFunction.resolverThunks.push(function () { - var rt = classFunction.container.resolveType(et); - addChildThunk(rt); - memberDefinition.elementType = rt; - }); - - } - } - } - - - //if (!classFunction) - - classFunction.resolveForwardDeclarations = function () { - classFunction.resolveForwardDeclarations = function () { }; - $data.Trace.log("resolving: " + classFunction.fullName); - this.resolverThunks.forEach(function (thunk) { - thunk(); - }); - //this.resolverThunks = []; - this.childResolverThunks.forEach(function (thunk) { - thunk(); - }); - //this.childResolverThunks = []; - } - - return memberDefinition; - }; - - MemberDefinition.prototype.toJSON = function () { - var property = {}; - for (var name in this) { - if (name !== 'defineBy' && name !== 'storageModel') { - if ((name === 'type' || name === 'dataType') && (this[name] && typeof this[name] === 'function')) { - try { - property[name] = Container.resolveName(this[name]); - } catch (e) { - property[name] = this[name]; - } - } else { - property[name] = this[name]; - } - } - } - return property; - } - - //TODO global/window - $data.MemberDefinition = window["MemberDefinition"] = MemberDefinition; - - var memberDefinitionPrefix = '$'; - function MemberDefinitionCollection() { }; - MemberDefinitionCollection.prototype = { - clearCache: function () { - this.arrayCache = undefined; - this.pubMapPropsCache = undefined; - this.keyPropsCache = undefined; - this.propByTypeCache = undefined; - this.pubMapMethodsCache = undefined; - this.pubMapPropNamesCache = undefined; - }, - asArray: function () { - if (!this.arrayCache) { - this.arrayCache = []; - for (var i in this) { - if (i.indexOf(memberDefinitionPrefix) === 0) - this.arrayCache.push(this[i]); - } - } - return this.arrayCache; - }, - getPublicMappedProperties: function () { - if (!this.pubMapPropsCache) { - this.pubMapPropsCache = []; - for (var i in this) { - if (i.indexOf(memberDefinitionPrefix) === 0 && this[i].kind == 'property' && !this[i].notMapped && this[i].enumerable) - this.pubMapPropsCache.push(this[i]); - } - } - return this.pubMapPropsCache;// || (this.pubMapPropsCache = this.asArray().filter(function (m) { return m.kind == 'property' && !m.notMapped && m.enumerable; })); - }, - getPublicMappedPropertyNames: function () { - if (!this.pubMapPropNamesCache) { - this.pubMapPropNamesCache = []; - for (var i in this) { - if (i.indexOf(memberDefinitionPrefix) === 0 && this[i].kind == 'property' && !this[i].notMapped && this[i].enumerable) - this.pubMapPropNamesCache.push(this[i].name); - } - } - return this.pubMapPropNamesCache; - }, - getKeyProperties: function () { - if (!this.keyPropsCache) { - this.keyPropsCache = []; - for (var i in this) { - if (i.indexOf(memberDefinitionPrefix) === 0 && this[i].kind == 'property' && this[i].key) - this.keyPropsCache.push(this[i]); - } - } - return this.keyPropsCache; - //return this.keyPropsCache || (this.keyPropsCache = this.asArray().filter(function (m) { return m.kind == 'property' && m.key; })); - }, - getPublicMappedMethods: function () { - if (!this.pubMapMethodsCache) { - this.pubMapMethodsCache = []; - for (var i in this) { - if (i.indexOf(memberDefinitionPrefix) === 0 && this[i].kind == 'method' && this[i].method/* && this.hasOwnProperty(i)*/) - this.pubMapMethodsCache.push(this[i]); - } - } - return this.pubMapMethodsCache; - }, - getPropertyByType: function (type) { - if (!this.propByTypeCache) { - this.propByTypeCache = []; - for (var i in this) { - if (i.indexOf(memberDefinitionPrefix) === 0 && this[i].dataType == type) - this.propByTypeCache.push(this[i]); - } - } - return this.propByTypeCache; - //return this.propByTypeCache || (this.propByTypeCache = this.asArray().filter(function (m) { return m.dataType == type; })); - }, - getMember: function (name) { return this[memberDefinitionPrefix + name]; }, - setMember: function (value) { this[memberDefinitionPrefix + value.name] = value; } - }; - MemberDefinitionCollection.prototype.constructor = MemberDefinitionCollection; - $data.MemberDefinitionCollection = window["MemberDefinitionCollection"] = MemberDefinitionCollection; - - function ClassEngineBase() { - this.classNames = {}; - } - - function MemberTypes() { - /// - /// - /// - /// - } - MemberTypes.__enum = true; - - MemberTypes.method = "method"; - MemberTypes.property = "property"; - MemberTypes.navProperty = "navProperty"; - MemberTypes.complexProperty = "complexProperty"; - MemberTypes.field = "field"; - - $data.MemberTypes = MemberTypes; - - //function classToJSON() { - // var ret = {}; - // for (var i in this) { - // if (this.hasOwnProperty(i)) { - // ret[i] = this[i]; - // } - // } - // return ret; - //} - //$data.Base.toJSON = classToJSON; - - ClassEngineBase.prototype = { - - //getClass: function (classReference) { - //}, - - //getProperties: function (classFunction) { - // return classFunction.propertyDefinitions; - //}, - - define: function (className, baseClass, container, instanceDefinition, classDefinition) { - /// - /// Creates a Jaydata type - /// Name of the class - /// Basetype of the class - /// - /// Class definition (properties, methods, etc) - /// Class static definition - /// - /// - /// var t = new $data.Class.define('Types.A', $data.Base, null, { - /// constructor: function(){ }, - /// func1: function(){ }, - /// member1: { type: 'string' } - /// }, { - /// staticFunc1: function() {} - /// }) - /// - /// - /// - - return this.defineEx(className, [{ type: baseClass }], container, instanceDefinition, classDefinition); - }, - defineEx: function (className, baseClasses, container, instanceDefinition, classDefinition) { - /// - /// Creates a Jaydata type - /// Name of the class - /// Basetypes of the class. First is a real base, others are mixins - /// - /// Class definition (properties, methods, etc) - /// Class static definition - /// - /// - /// var t = new $data.Class.define('Types.A', [$data.Base, $data.Mixin1, $data.Mixin2], null, { - /// constructor: function(){ }, - /// func1: function(){ }, - /// member1: { type: 'string' } - /// }, { - /// staticFunc1: function() {} - /// }) - /// - /// - /// - /// - /// Creates a Jaydata type - /// Name of the class - /// Basetypes of the class. First is a real base, others are mixins or propagations - /// - /// Class definition (properties, methods, etc) - /// Class static definition - /// - /// - /// var t = new $data.Class.define('Types.A', [ - /// { type: $data.Base, params: [1, 'secondParameterValue', new ConstructorParameter(0)] }, - /// { type: $data.Mixin1, }, - /// { type: $data.Mixin2, }, - /// { type: $data.Propagation1, params: [new ConstructorParameter(1)], propagateTo:'Propagation1' }, - /// { type: $data.Propagation2, params: ['firstParameterValue'], propagateTo:'Propagation2' } - /// ], null, { - /// constructor: function(){ }, - /// func1: function(){ }, - /// member1: { type: 'string' } - /// }, { - /// staticFunc1: function() {} - /// }) - /// - /// - /// - - container = container || $data.Container; - - if (baseClasses.length == 0) { - baseClasses.push({ type: $data.Base }); - } else if (baseClasses.length > 0 && !baseClasses[0].type) { - baseClasses[0].type = $data.Base; - } - for (var i = 0, l = baseClasses.length; i < l; i++) { - if (typeof baseClasses[i] === 'function') - baseClasses[i] = { type: baseClasses[i] }; - } - - var providedCtor = instanceDefinition ? instanceDefinition.constructor : undefined; - - var classNameParts = className.split('.'); - var shortClassName = classNameParts.splice(classNameParts.length - 1, 1)[0]; - - var root = container === $data.Container ? window : container; - for (var i = 0; i < classNameParts.length; i++) { - var part = classNameParts[i]; - if (!root[part]) { - var ns = {}; - ns.__namespace = true; - root[part] = ns; - } - root = root[part]; - } - - - var classFunction = null; - classFunction = this.classFunctionBuilder(shortClassName, baseClasses, classDefinition, instanceDefinition); - classFunction.fullName = className; - classFunction.namespace = classNameParts.join('.'); //classname splitted - classFunction.name = shortClassName; - classFunction.container = container; - classFunction.container.registerType(className, classFunction); - - this.buildType(classFunction, baseClasses, instanceDefinition, classDefinition); - - - - if (typeof intellisense !== 'undefined') { - if (instanceDefinition && instanceDefinition.constructor) { - intellisense.annotate(classFunction, instanceDefinition.constructor); - } - } - - root[shortClassName] = this.classNames[className] = classFunction; - //classFunction.toJSON = classToJSON; - var baseCount = classFunction.baseTypes.length; - for (var i = 0; i < baseCount; i++) { - var b = classFunction.baseTypes[i]; - if ("inheritedTypeProcessor" in b) { - b.inheritedTypeProcessor(classFunction); - } - } - //classFunction.prototype.constructor = instanceDefinition.constructor; - //classFunction.constructor = instanceDefinition.constructor; - //classFunction.toJSON = function () { return classFunction.memberDefinitions.filter( function(md) { return md; }; - return classFunction; - }, - classFunctionBuilder: function (name, base, classDefinition, instanceDefinition) { - var body = this.bodyBuilder(base, classDefinition, instanceDefinition); - return new Function('base', 'classDefinition', 'instanceDefinition', 'name', 'return function ' + name + ' (){ ' + - body + ' \n}; ')(base, classDefinition, instanceDefinition, name); - }, - bodyBuilder: function (bases, classDefinition, instanceDefinition) { - var mixin = ''; - var body = ''; - var propagation = ''; - - for (var i = 0, l = bases.length; i < l; i++) { - var base = bases[i]; - var index = i; - if (index == 0) { //ctor func - if (base && base.type && base.type !== $data.Base && base.type.fullName) { - body += ' var baseArguments = $data.typeSystem.createCtorParams(arguments, base[' + index + '].params, this); \n'; - body += ' ' + base.type.fullName + '.apply(this, baseArguments); \n'; - } - } else { - if (base && base.type && base.propagateTo) { - //propagation - propagation += ' ' + (!propagation ? 'var ' : '' + '') + 'propagationArguments = $data.typeSystem.createCtorParams(arguments, base[' + index + '].params, this); \n'; - propagation += ' this["' + base.propagateTo + '"] = Object.create(' + base.type.fullName + '.prototype); \n' + - ' ' + base.type.fullName + '.apply(this["' + base.propagateTo + '"], propagationArguments); \n'; - } - else if (base && base.type && base.type.memberDefinitions && base.type.memberDefinitions.$constructor && !base.propagateTo) { - //mixin - mixin += ' ' + base.type.fullName + '.memberDefinitions.$constructor.method.apply(this); \n'; - } - } - } - if (instanceDefinition && instanceDefinition.constructor != Object) - body += " instanceDefinition.constructor.apply(this, arguments); \n"; - - return '\n //mixins \n' + mixin + '\n //construction \n' + body + '\n //propagations \n' + propagation; - }, - - buildType: function (classFunction, baseClasses, instanceDefinition, classDefinition) { - var baseClass = baseClasses[0].type; - classFunction.inheritsFrom = baseClass; - - if (baseClass) { - classFunction.prototype = Object.create(baseClass.prototype); - classFunction.memberDefinitions = Object.create(baseClass.memberDefinitions || new MemberDefinitionCollection()); - classFunction.memberDefinitions.clearCache(); - - var staticDefs = baseClass.staticDefinitions; - if (staticDefs) { - staticDefs = staticDefs.asArray(); - if (staticDefs) { - for (var i = 0; i < staticDefs.length; i++) { - this.buildMember(classFunction, staticDefs[i], undefined, 'staticDefinitions'); - } - } - } - classFunction.baseTypes = baseClass.baseTypes ? [].concat(baseClass.baseTypes) : []; - for (var i = 0; i < baseClasses.length; i++) { - classFunction.baseTypes.push(baseClasses[i].type); - } - //classFunction.baseTypes = (baseClass.baseTypes || []).concat(baseClasses.map(function (base) { return base.type; })); - if (!classFunction.isAssignableTo) { - Object.defineProperty(classFunction, "isAssignableTo", { - value: function (type) { - return this === type || this.baseTypes.indexOf(type) >= 0; - }, - writable: false, - enumerable: false, - configurable: false - }); - } - } - - if (classDefinition) { - this.buildStaticMembers(classFunction, classDefinition); - - if (classDefinition.constructor) - classFunction.classConstructor = classDefinition.constructor; - } - - if (instanceDefinition) { - this.buildInstanceMembers(classFunction, instanceDefinition); - } - - var mixins = [].concat(baseClasses); - mixins.shift(); - if (Object.keys(mixins).length > 0) - this.buildInstanceMixins(classFunction, mixins); - - classFunction.__class = true; - - classFunction.prototype.constructor = classFunction; - - Object.defineProperty(classFunction.prototype, "getType", { - value: function () { - return classFunction; - }, - writable: false, - enumerable: false, - configurable: false - }); - }, - - addMethod: function (holder, name, method, propagation) { - if (!propagation || (typeof intellisense !== 'undefined')) { - holder[name] = method; - } else { - holder[name] = function () { - return method.apply(this[propagation], arguments); - }; - } - }, - - addProperty: function (holder, name, propertyDescriptor, propagation) { - - //holder[name] = {}; - - if (propagation) { - propertyDescriptor.configurable = true; - if (propertyDescriptor.get) { - var origGet = propertyDescriptor.get; - propertyDescriptor.get = function () { - if (!this[propagation]) - Guard.raise(new Exception("not inicialized")); - return origGet.apply(this[propagation], arguments); - }; - } - if (propertyDescriptor.set) { - var origSet = propertyDescriptor.set; - propertyDescriptor.set = function () { - if (!this[propagation]) - Guard.raise(new Exception("not inicialized")); - origSet.apply(this[propagation], arguments); - }; - } - } - - Object.defineProperty(holder, name, propertyDescriptor); - }, - - addField: function (holder, name, field) { - Guard.raise("not implemented"); - }, - - buildMethod: function (classFunction, memberDefinition, propagation) { - ///The object that will receive member - ///the newly added member - var holder = memberDefinition.classMember ? classFunction : classFunction.prototype; - this.addMethod(holder, memberDefinition.name, memberDefinition.method, propagation); - }, - - buildProperty: function (classFunction, memberDefinition, propagation) { - ///The object that will receive member - ///the newly added member - var holder = memberDefinition.classMember ? classFunction : classFunction.prototype; - var pd = memberDefinition.createPropertyDescriptor(classFunction); - this.addProperty(holder, memberDefinition.name, pd, propagation); - - //if lazyload TODO - if (!memberDefinition.classMember && classFunction.__setPropertyfunctions == true && memberDefinition.withoutGetSetMethod !== true && - !('get_' + memberDefinition.name in holder || 'set_' + memberDefinition.name in holder)) { - var pdGetMethod = memberDefinition.createGetMethod(); - this.addProperty(holder, 'get_' + memberDefinition.name, pdGetMethod, propagation); - - var pdSetMethod = memberDefinition.createSetMethod(); - this.addProperty(holder, 'set_' + memberDefinition.name, pdSetMethod, propagation); - } - }, - - - buildMember: function (classFunction, memberDefinition, propagation, memberCollectionName) { - /// - memberCollectionName = memberCollectionName || 'memberDefinitions'; - classFunction[memberCollectionName] = classFunction[memberCollectionName] || new MemberDefinitionCollection(); - classFunction[memberCollectionName].setMember(memberDefinition); - - switch (memberDefinition.kind) { - case MemberTypes.method: - this.buildMethod(classFunction, memberDefinition, propagation); - break; - case MemberTypes.navProperty: - case MemberTypes.complexProperty: - case MemberTypes.property: - this.buildProperty(classFunction, memberDefinition, propagation); - break; - default: Guard.raise("Unknown member type: " + memberDefinition.kind + "," + memberDefinition.name); - } - }, - - buildStaticMembers: function (classFunction, memberListDefinition) { - ///The class constructor that will be extended - /// - var t = this; - for (var item in memberListDefinition) { - if (memberListDefinition.hasOwnProperty(item)) { - var memberDefinition = MemberDefinition.translateDefinition(memberListDefinition[item], item, classFunction); - memberDefinition.classMember = true; - t.buildMember(classFunction, memberDefinition, undefined, 'staticDefinitions'); - } - } - }, - - buildInstanceMembers: function (classFunction, memberListDefinition) { - ///The class constructor whose prototype will be extended - /// - ///pinning t outside of the closure seems actually faster then passing in the this and referencing - var t = this; - for (var item in memberListDefinition) { - if (memberListDefinition.hasOwnProperty(item)) { - var memberDefinition = MemberDefinition.translateDefinition(memberListDefinition[item], item, classFunction); - t.buildMember(classFunction, memberDefinition, undefined, 'memberDefinitions'); - } - } - }, - - copyMembers: function (sourceType, targetType) { - /// - /// - function il(msg) { - if (typeof intellisense === 'undefined') { - return; - } - intellisense.logMessage(msg); - } - - Object.keys(sourceType.prototype).forEach(function (item, i, src) { - if (item !== 'constructor' && item !== 'toString') { - il("copying item:" + item); - targetType.prototype[item] = sourceType[item]; - } - }); - }, - - buildInstanceMixins: function (classFunction, mixinList) { - ///The class constructor whose prototype will be extended - /// - - classFunction.mixins = classFunction.mixins || []; - classFunction.propagations = classFunction.propagations || []; - - for (var i = 0; i < mixinList.length; i++) { - var item = mixinList[i]; - //if (classFunction.memberDefinitions.getMember(item.type.name)) { - if (item.propagateTo) { - this.buildInstancePropagation(classFunction, item); - classFunction.propagations.push(item); - classFunction.propagations[item.type.name] = true; - } else { - this.buildInstanceMixin(classFunction, item); - classFunction.mixins.push(item); - classFunction.mixins[item.type.name] = true; - } - }; - }, - buildInstanceMixin: function (classFunction, typeObj) { - ///The class constructor whose prototype will be extended - /// - - var memberDefs = typeObj.type.memberDefinitions.asArray(); - for (var i = 0, l = memberDefs.length; i < l; i++) { - var itemName = memberDefs[i].name; - if (itemName !== 'constructor' && !classFunction.memberDefinitions.getMember(itemName)) { - this.buildMember(classFunction, memberDefs[i]); - } - } - - if (typeObj.type.staticDefinitions) { - var staticDefs = typeObj.type.staticDefinitions.asArray(); - for (var i = 0, l = staticDefs.length; i < l; i++) { - var itemName = staticDefs[i].name; - if (itemName !== 'constructor' && !classFunction.memberDefinitions.getMember(itemName)) { - this.buildMember(classFunction, staticDefs[i], undefined, 'staticDefinitions'); - } - } - } - }, - buildInstancePropagation: function (classFunction, typeObj) { - ///The class constructor whose prototype will be extended - /// - - var memberDefs = typeObj.type.memberDefinitions.asArray(); - for (var i = 0, l = memberDefs.length; i < l; i++) { - var itemName = memberDefs[i].name; - if (itemName !== 'constructor' && !classFunction.memberDefinitions.getMember(itemName)) { - this.buildMember(classFunction, memberDefs[i], typeObj.propagateTo); - } - } - } - - }; - - $data.Class = Class = new ClassEngineBase(); - - //(function (global) { - global = window; - function ContainerCtor(parentContainer) { - var parent = parentContainer; - if (parent) { - parent.addChildContainer(this); - } - - var classNames = {}; - var consolidatedClassNames = []; - var classTypes = []; - - this.classNames = classNames; - this.consolidatedClassNames = consolidatedClassNames; - this.classTypes = classTypes; - - var mappedTo = []; - this.mappedTo = mappedTo; - - var self = this; - - this["holder"] = null; - - var IoC = function (type, parameters) { - var t = self.resolveType(type); - var inst = Object.create(t.prototype); - t.apply(inst, parameters); - return inst; - }; - - var pendingResolutions = {}; - this.pendingResolutions = pendingResolutions; - - function addPendingResolution(name, onResolved) { - pendingResolutions[name] = pendingResolutions[name] || []; - pendingResolutions[name].push(onResolved); - } - - this.addChildContainer = function (container) { - //children.push(container); - } - - this.createInstance = function (type, parameters) { return IoC(type, parameters); }; - - this.mapType = function (aliasTypeOrName, realTypeOrName) { - Guard.requireValue("aliasType", aliasTypeOrName); - Guard.requireValue("realType", realTypeOrName); - var aliasT = this.getType(aliasTypeOrName); - var realT = this.getType(realTypeOrName); - var aliasPos = classTypes.indexOf(aliasT); - var realPos = classTypes.indexOf(realT); - mappedTo[aliasPos] = realPos; - }, - - //this.resolve = function (type, parameters) { - // var classFunction = this.resolveType(type, parameters); - // return new classFunction(parameters); - //}; - - - - this.isPrimitiveType = function (type) { - var t = this.resolveType(type); - - switch (true) { - case t === Number: - case t === String: - case t === Date: - case t === Boolean: - case t === Array: - case t === Object: - - case t === $data.Number: - case t === $data.Integer: - case t === $data.Date: - case t === $data.String: - case t === $data.Boolean: - case t === $data.Array: - case t === $data.Object: - case t === $data.Guid: - - case t === $data.Byte: - case t === $data.SByte: - case t === $data.Decimal: - case t === $data.Float: - case t === $data.Int16: - case t === $data.Int32: - case t === $data.Int64: - case t === $data.DateTimeOffset: - case t === $data.Time: - - case t === $data.SimpleBase: - case t === $data.Geospatial: - case t === $data.GeographyBase: - case t === $data.GeographyPoint: - case t === $data.GeographyLineString: - case t === $data.GeographyPolygon: - case t === $data.GeographyMultiPoint: - case t === $data.GeographyMultiLineString: - case t === $data.GeographyMultiPolygon: - case t === $data.GeographyCollection: - case t === $data.GeometryBase: - case t === $data.GeometryPoint: - case t === $data.GeometryLineString: - case t === $data.GeometryPolygon: - case t === $data.GeometryMultiPoint: - case t === $data.GeometryMultiLineString: - case t === $data.GeometryMultiPolygon: - case t === $data.GeometryCollection: - - return true; - default: - return false; - } - - //return t === Number || t === String || t === Date || t === String || t === Boolean || t === Array || t === Object || - // t === $data.Number || t === $data.Integer || t === $data.Date || t === $data.String || t === $data.Boolean || t === $data.Array || t === $data.Object || - // t === $data.GeographyPoint || t === $data.Guid; - }; - - - this.resolveName = function (type) { - var t = this.resolveType(type); - var tPos = classTypes.indexOf(t); - return consolidatedClassNames[tPos]; - }; - - this.resolveType = function (typeOrName, onResolved) { - //if ("string" === typeof typeOrName) { - // console.log("@@@@String type!!!", typeOrName) - //} - var t = typeOrName; - t = this.getType(t, onResolved ? true : false, onResolved); - var posT = classTypes.indexOf(t); - return typeof mappedTo[posT] === 'undefined' ? t : classTypes[mappedTo[posT]]; - }; - - - - this.getType = function (typeOrName, doNotThrow, onResolved) { - Guard.requireValue("typeOrName", typeOrName); - if (typeof typeOrName === 'function') { - return typeOrName; - }; - - if (!(typeOrName in classNames)) { - if (parent) { - var tp = parent.getType(typeOrName, true); - if (tp) return tp; - } - if (onResolved) { - addPendingResolution(typeOrName, onResolved); - return; - } - else if (doNotThrow) { - return undefined; - } else { - Guard.raise(new Exception("Unable to resolve type:" + typeOrName)); - } - }; - var result = classTypes[classNames[typeOrName]]; - if (onResolved) { - onResolved(result); - } - return result; - }; - - this.getName = function (typeOrName) { - var t = this.getType(typeOrName); - var tPos = classTypes.indexOf(t); - if (tPos == -1) - Guard.raise("unknown type to request name for: " + typeOrName); - return consolidatedClassNames[tPos]; - }; - - this.getTypes = function () { - var keys = Object.keys(classNames); - var ret = []; - for (var i = 0; i < keys.length; i++) { - var className = keys[i]; - ret.push({ name: className, type: classTypes[classNames[className]], toString: function () { return this.name; } }); - } - return ret; - }; - - //this.getTypeName( in type); - //this.resolveType() - //this.inferTypeFromValue = function (value) { - - this.getTypeName = function (value) { - //TODO refactor - switch (typeof value) { - case 'object': - if (value == null) return '$data.Object'; - if (value instanceof Array) return '$data.Array'; - if (value.getType) return value.getType().fullName; - if (value instanceof Date) return '$data.Date'; - if (value instanceof $data.Guid) return '$data.Guid'; - if (value instanceof $data.DateTimeOffset) return '$data.DateTimeOffset'; - if (value instanceof $data.GeographyPoint) return '$data.GeographyPoint'; - if (value instanceof $data.GeographyLineString) return '$data.GeographyLineString'; - if (value instanceof $data.GeographyPolygon) return '$data.GeographyPolygon'; - if (value instanceof $data.GeographyMultiPoint) return '$data.GeographyMultiPoint'; - if (value instanceof $data.GeographyMultiLineString) return '$data.GeographyMultiLineString'; - if (value instanceof $data.GeographyMultiPolygon) return '$data.GeographyMultiPolygon'; - if (value instanceof $data.GeographyCollection) return '$data.GeographyCollection'; - if (value instanceof $data.GeographyBase) return '$data.GeographyBase'; - if (value instanceof $data.GeometryPoint) return '$data.GeometryPoint'; - if (value instanceof $data.GeometryLineString) return '$data.GeometryLineString'; - if (value instanceof $data.GeometryPolygon) return '$data.GeometryPolygon'; - if (value instanceof $data.GeometryMultiPoint) return '$data.GeometryMultiPoint'; - if (value instanceof $data.GeometryMultiLineString) return '$data.GeometryMultiLineString'; - if (value instanceof $data.GeometryMultiPolygon) return '$data.GeometryMultiPolygon'; - if (value instanceof $data.GeometryCollection) return '$data.GeometryCollection'; - if (value instanceof $data.GeometryBase) return '$data.GeometryBase'; - if (value instanceof $data.Geospatial) return '$data.Geospatial'; - if (value instanceof $data.SimpleBase) return '$data.SimpleBase'; - if (typeof value.toHexString === 'function') return '$data.ObjectID'; - //if(value instanceof "number") return - default: - return typeof value; - } - }; - - this.isTypeRegistered = function (typeOrName) { - if (typeof typeOrName === 'function') { - return classTypes.indexOf(typeOrName) > -1; - } else { - return typeOrName in classNames; - } - }; - - this.unregisterType = function (type) { - Guard.raise("Unimplemented"); - }; - - - - this.getDefault = function (typeOrName) { - var t = this.resolveType(typeOrName); - switch (t) { - case $data.Number: return 0.0; - case $data.Float: return 0.0; - case $data.Decimal: return '0.0'; - case $data.Integer: return 0; - case $data.Int16: return 0; - case $data.Int32: return 0; - case $data.Int64: return '0'; - case $data.Byte: return 0; - case $data.SByte: return 0; - case $data.String: return null; - case $data.Boolean: return false; - default: return null; - } - }; - - //name array ['', '', ''] - this.getIndex = function (typeOrName) { - var t = this.resolveType(typeOrName); - return classTypes.indexOf(t); - } - - this.resolveByIndex = function (index) { - return classTypes[index]; - } - - this.registerType = function (nameOrNamesArray, type, factoryFunc) { - /// - ///Registers a type and optionally a lifetimeManager with a name - ///that can be used to later resolve the type or create new instances - ///The names of the type - ///The type to register - /// - /// - /// - ///Registers a new type that - ///The name of the type - ///The type to register - /// - - - ///TODO remove - /*if (typeof typeNameOrAlias === 'string') { - if (classNames.indexOf(typeNameOrAlias) > -1) { - Guard.raise("Type already registered. Remove first"); - } - }*/ - - if (!nameOrNamesArray) { - return; - } - - //todo add ('number', 'number') - if (typeof type === "string") { - type = self.resolveType(type); - } - - var namesArray = []; - if (typeof nameOrNamesArray === 'string') { - var tmp = []; - tmp.push(nameOrNamesArray); - namesArray = tmp; - } else { - namesArray = nameOrNamesArray; - } - - for (var i = 0; i < namesArray.length; i++) { - var parts = namesArray[i].split('.'); - var item = {}; - item.shortName = parts[parts.length - 1]; - item.fullName = namesArray[i]; - namesArray[i] = item; - } - - //if (type. - - - var creatorFnc = function () { return IoC(type, arguments); }; - - if (typeof intellisense !== 'undefined') { - intellisense.annotate(creatorFnc, type); - } - - for (var i = 0, l = namesArray.length; i < l; i++) { - var item = namesArray[i]; - if (!(("create" + item.shortName) in self)) { - if (typeof factoryFunc === 'function') { - self["create" + item.shortName] = factoryFunc; - } else { - self["create" + item.shortName] = creatorFnc; - } - } - - var typePos = classTypes.indexOf(type); - if (typePos == -1) { - //new type - typePos = classTypes.push(type) - 1; - var fn = item.fullName; - consolidatedClassNames[typePos] = item.fullName; - }; - - classNames[item.fullName] = typePos; - - var pending = pendingResolutions[item.fullName] || []; - if (pending.length > 0) { - pending.forEach(function (t) { - t(type); - }); - pendingResolutions[item.fullName] = []; - } - } - if (parent) { - parent.registerType.apply(parent, arguments); - } - if (!type.name) { - type.name = namesArray[0].shortName; - } - }; - - - var _converters = { - from: {}, - to: {} - }; - this.converters = _converters; - - this.convertTo = function (value, tType, eType /*if Array*/, options) { - Guard.requireValue("typeOrName", tType); - - if(Object.isNullOrUndefined(value)) - return value; - - var sourceTypeName = Container.getTypeName(value); - var sourceType = Container.resolveType(sourceTypeName); - var sourceTypeName = Container.resolveName(sourceType); - var targetType = Container.resolveType(tType); - var targetTypeName = Container.resolveName(targetType); - - var result; - try { - if (typeof targetType['from' + sourceTypeName] === 'function') { - // target from - result = targetType['from' + sourceTypeName].apply(targetType, arguments); - - } else if (typeof sourceType['to' + targetTypeName] === 'function') { - // source to - result = sourceType['to' + targetTypeName].apply(sourceType, arguments); - - } else if (_converters.to[targetTypeName] && _converters.to[targetTypeName][sourceTypeName]) { - // target from source - result = _converters.to[targetTypeName][sourceTypeName].apply(_converters, arguments); - - } else if (_converters.from[sourceTypeName] && _converters.from[sourceTypeName][targetTypeName]) { - // source to target - result = _converters.from[sourceTypeName][targetTypeName].apply(_converters, arguments); - - } else if (targetTypeName === sourceTypeName || value instanceof targetType) { - result = value; - - } else if (_converters.to[targetTypeName] && _converters.to[targetTypeName]['default']) { - // target from anything - result = _converters.to[targetTypeName]['default'].apply(_converters, arguments); - - } else { - throw "converter not found"; - } - } catch (e) { - Guard.raise(new Exception("Value '" + sourceTypeName + "' not convertable to '" + targetTypeName + "'", 'TypeError', value)); - } - - if (targetType === $data.Array && eType && Array.isArray(result)) { - for (var i = 0; i < result.length; i++) { - result[i] = this.convertTo.call(this, result[i], eType, undefined, options); - } - } - - return result; - }; - this.registerConverter = function (target, sourceOrToConverters, toConverterOrFromConverters, fromConverter) { - //registerConverter($data.Guid, { $data.String: fn, int: fn }, { string: fn, int:fn }) - //registerConverter($data.Guid, $data.String, fn, fn); - - var targetName = Container.resolveName(target); - if (Container.isTypeRegistered(sourceOrToConverters)) { - //isSource - _converters.to[targetName] = _converters.to[targetName] || {}; - _converters.from[targetName] = _converters.from[targetName] || {}; - - var sourceName = Container.resolveName(sourceOrToConverters); - - if (toConverterOrFromConverters) - _converters.to[targetName][sourceName] = toConverterOrFromConverters; - if (fromConverter) - _converters.from[targetName][sourceName] = fromConverter; - - } else { - // converterGroup - - //fromConverters - if (_converters.to[targetName]) { - _converters.to[targetName] = $data.typeSystem.extend(_converters.to[targetName], sourceOrToConverters); - } else { - _converters.to[targetName] = sourceOrToConverters; - } - - //toConverters - if (_converters.from[targetName]) { - _converters.from[targetName] = $data.typeSystem.extend(_converters.from[targetName], toConverterOrFromConverters); - } else { - _converters.from[targetName] = toConverterOrFromConverters; - } - } - }; - } - $data.ContainerClass = ContainerCtor; - - var c; - - global["Container"] = $data.Container = c = global["C$"] = new ContainerCtor(); - - $data.createContainer = function () { - return new ContainerCtor($data.Container); - } - - //})(window); - - global["$C"] = function () { Class.define.apply(Class, arguments); }; - - - var storeProperty = function (memberDefinition, value) { - var backingFieldName = "_" + memberDefinition.name; - if (!this[backingFieldName]) { - Object.defineProperty(this, backingFieldName, memberDefinition.createStorePropertyDescriptor(value)); - } - else { - this[backingFieldName] = value; - } - }; - var retrieveProperty = function (memberDefinition) { - var backingFieldName = "_" + memberDefinition.name; - return this[backingFieldName]; - }; - - - $data.Class.define('$data.Base', function Base() { }, null, { - storeProperty: storeProperty, - retrieveProperty: retrieveProperty, - setProperty: function (memberDefinition, value, callback) { - this[memberDefinition.name] = value; - callback(); - }, - getProperty: function (memberDefinition, callback) { - callback.apply(this, [this[memberDefinition.name]]); - } - }, { - create: function () { return Container.createInstance(this, arguments); }, - extend: function (name, container, instanceDefinition, classDefinition) { - if (container && !(container instanceof ContainerCtor)) { - classDefinition = instanceDefinition; - instanceDefinition = container; - container = undefined; - } - return $data.Class.define(name, this, container, instanceDefinition, classDefinition); - }, - getMemberDefinition: function (name) { - return this.memberDefinitions.getMember(name); - }, - addProperty: function (name, getterOrType, setterOrGetter, setter) { - var _getter = getterOrType; - var _setter = setterOrGetter; - var _type; - if (typeof _getter === 'string') { - _type = getterOrType; - _getter = setterOrGetter; - _setter = setter; - } - - var propDef = { - notMapped: true, - storeOnObject: true, - get: typeof _getter === 'function' ? _getter : function () { }, - set: typeof _setter === 'function' ? _setter : function () { }, - type: _type - }; - - var memberDefinition = MemberDefinition.translateDefinition(propDef, name, this); - $data.Class.buildMember(this, memberDefinition); - - this.memberDefinitions.clearCache(); - - return this; - }, - addMember: function (name, definition, isClassMember) { - var memberDefinition = MemberDefinition.translateDefinition(definition, name, this); - - if (isClassMember) { - memberDefinition.classMember = true; - $data.Class.buildMember(this, memberDefinition, undefined, 'staticDefinitions'); - this.staticDefinitions.clearCache(); - } else { - $data.Class.buildMember(this, memberDefinition); - this.memberDefinitions.clearCache(); - } - return this; - }, - describeField: function (name, definition) { - var memDef = this.memberDefinitions.getMember(name); - if (!memDef) { - this.addMember(name, definition); - } else { - Guard.raise(new Exception("Field '" + name + "' already defined!", "Invalid operation")); - } - return this; - }, - storeProperty: storeProperty, - retrieveProperty: retrieveProperty, - 'from$data.Object': function (value) { - return value; - } - }); - - - //override after typeSystem initialized - - - $data.Class.ConstructorParameter = ConstructorParameter = $data.Class.define('ConstructorParameter', null, null, { - constructor: function (paramIndex) { - /// - this.paramIndex = paramIndex; - }, - paramIndex: {} - }); - /*$data.Class.MixinParameter = MixinParameter = $data.Class.define('MixinParameter', null, null, { - constructor: function (typeName) { - /// - this.typeName = typeName; - }, - typeName: {} - });*/ - - //var e = new Entity(); - - - /*$data.Interface = Class.define("Interface", null, null, { - constructor: function() { Guard.raise("Can not create an interface"); } - }, - { - define: function (name, definition) { - var result = Class.define(name, $data.Interface, null, null, definition); - delete result.__class; - result.__interface = true; - return result; - } - }); - - - - $data.Observable = Observable = Class.define("Observable", null, null, { - propertyChanged: { dataType: $data.Event } - }, { - createFromInstance: function(instance) { - var propNames = instance.getClass().memberDefinitions.f - } - });*/ - - - -})($data, window); - -$data.defaultErrorCallback = function () { - //console.log('DEFAULT ERROR CALLBACK:'); - /*if (console.dir) - console.dir(arguments); - else - console.log(arguments);*/ - if (arguments.length > 0 && arguments[arguments.length - 1] && typeof arguments[arguments.length - 1].reject === 'function') { - (console.error || console.log).call(console, arguments[0]); - arguments[arguments.length - 1].reject.apply(arguments[arguments.length - 1], arguments); - } else { - if (arguments[0] instanceof Error) { - Guard.raise(arguments[0]); - } else { - Guard.raise(new Exception("DEFAULT ERROR CALLBACK!", "DefaultError", arguments)); - } - } -}; -$data.defaultSuccessCallback = function () { /*console.log('DEFAULT SUCCES CALLBACK');*/ }; -$data.defaultNotifyCallback = function () { /*console.log('DEFAULT NOTIFY CALLBACK');*/ }; - -$data.typeSystem = { - __namespace: true, - /*inherit: function (ctor, baseType) { - var proto = new baseType(); - ctor.prototype = $.extend(proto, ctor.prototype); - //console.dir(proto); - ctor.prototype.base = new baseType(); - //console.dir(ctor.prototype.base); - ctor.prototype.constructor = ctor; - return ctor; - },*/ - //mix: function (type, mixin) { - // type.prototype = $.extend(type.prototype || {}, mixin.prototype || {}); - // type.mixins = type.mixins || []; - // type.mixins.push(mixin); - // return type; - //}, - extend: function (target) { - /// - /// Extends an object with properties of additional parameters. - /// - /// - /// Object that will be extended. - /// Object to extend target with. - /// Object to extend target with. - /// - /// - if (typeof target !== 'object' && typeof target !== 'function') - Guard.raise('Target must be object or function'); - - for (var i = 1; i < arguments.length; i++) { - var obj = arguments[i]; - if (obj === null || typeof obj === 'undefined') - continue; - for (key in obj) { - target[key] = obj[key]; - } - } - return target; - }, - createCallbackSetting: function (callBack, defaultSetting) { - var setting = { - success: $data.defaultSuccessCallback, - error: $data.defaultErrorCallback, - notify: $data.defaultNotifyCallback - }; - - if (defaultSetting != undefined && defaultSetting != null) { - setting = defaultSetting; - } - - var result; - if (callBack == null || callBack == undefined) { - result = setting; - - } else if (typeof callBack == 'function') { - result = this.extend(setting, { success: callBack }); - - } else { - result = this.extend(setting, callBack); - } - - function wrapCode(fn) { var t = this; function r() { fn.apply(t, arguments); fn = function () { } } return r; } - - if (typeof result.error === 'function') - result.error = wrapCode(result.error); - - return result; - }, - createCtorParams: function (source, indexes, thisObj) { - ///Paramerter array - /// - /// - if (indexes) { - var paramArray = []; - for (var i = 0, l = indexes.length; i < l; i++) { - var item = i; - if (indexes[item] instanceof ConstructorParameter) - paramArray.push(source[indexes[item].paramIndex]); - else if (typeof indexes[item] === "function") - paramArray.push(indexes[item].apply(thisObj)); - else - paramArray.push(indexes[item]); - } - return paramArray; - } - return source; - }, - writePropertyValues: function (obj) { - if (obj && obj.getType && obj.getType().memberDefinitions) { - this.writeProperties(obj, obj.getType().memberDefinitions.asArray().filter( - function (md) { return (md.kind == "property" || md.kind == "navProperty" || md.kind == "complexProperty") && !md.prototypeProperty; } - )); - } - }, - writeProperties: function (obj, members) { - var defines = {}; - for (var i = 0, l = members.length; i < l; i++) { - var memDef = members[i]; - defines[memDef.name] = memDef.createPropertyDescriptor(null, memDef.value); - } - - Object.defineProperties(obj, defines); - - }, - writeProperty: function (obj, member, value) { - var memDef = typeof member === 'string' ? obj.getType().memberDefinitions.getMember(member) : member; - if (memDef) { - var propDef = memDef.createPropertyDescriptor(null, value); - //////OPTIMIZATION - Object.defineProperty(obj, memDef.name, propDef); - } - } -}; - -$data.debug = function () { - (console.debug || console.log).apply(console, arguments); -}; - -$data.debugWith = function () { - var cArgs = arguments; - return function (r) { - (console.debug || console.log).apply(console, cArgs); - if ((typeof Error !== 'undefined' && r instanceof Error) || - (typeof Exception !== 'undefined' && r instanceof Exception)) { - (console.error || console.log).apply(console, arguments); - } else { - (console.debug || console.log).apply(console, arguments); - } - } -}; - -$data.fdebug = { - success: $data.debugWith('success'), - error: $data.debugWith('error') -}; -$data.Number = typeof Number !== 'undefined' ? Number : function JayNumber() { }; -$data.Date = typeof Date !== 'undefined' ? Date : function JayDate() { }; -$data.String = typeof String !== 'undefined' ? String : function JayString() { }; -$data.Boolean = typeof Boolean !== 'undefined' ? Boolean : function JayBoolean() { }; -$data.Array = typeof Array !== 'undefined' ? Array : function JayArray() { }; -$data.Object = typeof Object !== 'undefined' ? Object : function JayObject() { }; -$data.Function = Function; - -$data.Byte = function JayByte() { }; -$data.SByte = function JaySByte() { }; -$data.Decimal = function JayDecimal() { }; -$data.Float = $data.Single = function JayFloat() { }; -$data.Integer = function JayInteger() { }; -$data.Int16 = function JayInt16(v) { }; -$data.Int32 = function JayInt32() { }; -$data.Int64 = function JayInt64(v) { }; -$data.ObjectID = typeof $data.mongoDBDriver !== 'undefined' && typeof $data.mongoDBDriver.ObjectID !== 'undefined' ? $data.mongoDBDriver.ObjectID : function JayObjectID() { }; -$data.Time = function JayTime() { }; -$data.DateTimeOffset = function JayDateTimeOffset(val) { - this.value = val; -}; -$data.DateTimeOffset.prototype.toJSON = function () { - return this.value instanceof Date ? this.value.toISOString() : this.value; -}; - -$data.Container.registerType(["$data.Number", "number", "JayNumber", "double"], $data.Number); -$data.Container.registerType(["$data.Integer", "int", "integer", "JayInteger"], $data.Integer); -$data.Container.registerType(["$data.Int32", "int32", "JayInt32"], $data.Int32); -$data.Container.registerType(["$data.Byte", "byte", "JayByte"], $data.Byte); -$data.Container.registerType(["$data.SByte", "sbyte", "JaySByte"], $data.SByte); -$data.Container.registerType(["$data.Decimal", "decimal", "JayDecimal"], $data.Decimal); -$data.Container.registerType(["$data.Float", "$data.Single", "float", "single", "JayFloat"], $data.Float); -$data.Container.registerType(["$data.Int16", "int16", "word", "JayInt16"], $data.Int16); -$data.Container.registerType(["$data.Int64", "int64", "long", "JayInt64"], $data.Int64); -$data.Container.registerType(["$data.String", "string", "text", "character", "JayString"], $data.String); -$data.Container.registerType(["$data.Array", "array", "Array", "[]", "JayArray"], $data.Array, function () { - return $data.Array.apply(undefined, arguments); -}); -$data.Container.registerType(["$data.Date", "datetime", "date", "JayDate"], $data.Date); -$data.Container.registerType(["$data.Time", "time", "JayTime"], $data.Time); -$data.Container.registerType(["$data.DateTimeOffset", "offset", "datetimeoffset", "JayDateTimeOffset"], $data.DateTimeOffset); -$data.Container.registerType(["$data.Boolean", "bool", "boolean", "JayBoolean"], $data.Boolean); -$data.Container.registerType(["$data.Object", "Object", "object", "{}", "JayObject"], $data.Object); -$data.Container.registerType(["$data.Function", "Function", "function"], $data.Function); -$data.Container.registerType(['$data.ObjectID', 'ObjectID', 'objectId', 'objectid', 'ID', 'Id', 'id', 'JayObjectID'], $data.ObjectID); -$data.Class.define('$data.TraceBase', null, null, { - log: function () { }, - warn: function () { }, - error: function () { } -}); - -$data.Trace = new $data.TraceBase(); -$data.Class.define('$data.Logger', $data.TraceBase, null, { - log: function () { - Array.prototype.unshift.call(arguments, this.getDateFormat()); - console.log.apply(console, arguments); - }, - warn: function () { - Array.prototype.unshift.call(arguments, this.getDateFormat()); - console.warn.apply(console, arguments); - }, - error: function () { - Array.prototype.unshift.call(arguments, this.getDateFormat()); - console.error.apply(console, arguments); - }, - - getDateFormat: function () { - var date = new Date(); - return date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds() + '.' + date.getMilliseconds(); - } -}); -$data.Number = typeof Number !== 'undefined' ? Number : function JayNumber() { }; -$data.Date = typeof Date !== 'undefined' ? Date : function JayDate() { }; -$data.String = typeof String !== 'undefined' ? String : function JayString() { }; -$data.Boolean = typeof Boolean !== 'undefined' ? Boolean : function JayBoolean() { }; -$data.Array = typeof Array !== 'undefined' ? Array : function JayArray() { }; -$data.Object = typeof Object !== 'undefined' ? Object : function JayObject() { }; -$data.Function = Function; - -$data.Byte = function JayByte() { }; -$data.SByte = function JaySByte() { }; -$data.Decimal = function JayDecimal() { }; -$data.Float = $data.Single = function JayFloat() { }; -$data.Integer = function JayInteger() { }; -$data.Int16 = function JayInt16(v) { }; -$data.Int32 = function JayInt32() { }; -$data.Int64 = function JayInt64(v) { }; -$data.ObjectID = typeof $data.mongoDBDriver !== 'undefined' && typeof $data.mongoDBDriver.ObjectID !== 'undefined' ? $data.mongoDBDriver.ObjectID : function JayObjectID() { }; -$data.Time = function JayTime() { }; -$data.DateTimeOffset = function JayDateTimeOffset(val) { - this.value = val; -}; -$data.DateTimeOffset.prototype.toJSON = function () { - return this.value instanceof Date ? this.value.toISOString() : this.value; -}; - -$data.Container.registerType(["$data.Number", "number", "JayNumber", "double"], $data.Number); -$data.Container.registerType(["$data.Integer", "int", "integer", "JayInteger"], $data.Integer); -$data.Container.registerType(["$data.Int32", "int32", "JayInt32"], $data.Int32); -$data.Container.registerType(["$data.Byte", "byte", "JayByte"], $data.Byte); -$data.Container.registerType(["$data.SByte", "sbyte", "JaySByte"], $data.SByte); -$data.Container.registerType(["$data.Decimal", "decimal", "JayDecimal"], $data.Decimal); -$data.Container.registerType(["$data.Float", "$data.Single", "float", "single", "JayFloat"], $data.Float); -$data.Container.registerType(["$data.Int16", "int16", "word", "JayInt16"], $data.Int16); -$data.Container.registerType(["$data.Int64", "int64", "long", "JayInt64"], $data.Int64); -$data.Container.registerType(["$data.String", "string", "text", "character", "JayString"], $data.String); -$data.Container.registerType(["$data.Array", "array", "Array", "[]", "JayArray"], $data.Array, function () { - return $data.Array.apply(undefined, arguments); -}); -$data.Container.registerType(["$data.Date", "datetime", "date", "JayDate"], $data.Date); -$data.Container.registerType(["$data.Time", "time", "JayTime"], $data.Time); -$data.Container.registerType(["$data.DateTimeOffset", "offset", "datetimeoffset", "JayDateTimeOffset"], $data.DateTimeOffset); -$data.Container.registerType(["$data.Boolean", "bool", "boolean", "JayBoolean"], $data.Boolean); -$data.Container.registerType(["$data.Object", "Object", "object", "{}", "JayObject"], $data.Object); -$data.Container.registerType(["$data.Function", "Function", "function"], $data.Function); -$data.Container.registerType(['$data.ObjectID', 'ObjectID', 'objectId', 'objectid', 'ID', 'Id', 'id', 'JayObjectID'], $data.ObjectID); -/* $data.SimpleBase */ -$data.SimpleBase = function SimpleBase(data) { - if (typeof data === 'object' && data) { - if (Array.isArray(this.constructor.validMembers)) { - for (var i = 0; i < this.constructor.validMembers.length; i++) { - var name = this.constructor.validMembers[i]; - - if (data[name] !== undefined) { - this[name] = data[name]; - } - } - - } else { - delete data.type; - $data.typeSystem.extend(this, data); - } - } -} -$data.SimpleBase.registerType = function (name, type, base) { - base = base || $data.SimpleBase; - - type.type = name; - type.prototype = Object.create(base.prototype); - type.prototype.constructor = type; -} -$data.Container.registerType(['$data.SimpleBase', 'SimpleBase'], $data.SimpleBase);$data.Geospatial = function Geospatial() { - this.type = this.constructor.type; - if (Array.isArray(this.constructor.validMembers)) { - for (var i = 0; i < this.constructor.validMembers.length; i++) { - var name = this.constructor.validMembers[i]; - this[name] = undefined; - } - } - - $data.SimpleBase.apply(this, arguments); - this.type = this.constructor.type || 'Unknown'; -}; -$data.SimpleBase.registerType('Geospatial', $data.Geospatial); -$data.Container.registerType(['$data.Geospatial', 'Geospatial'], $data.Geospatial); - -$data.point = function (arg) { - if (arg && arg.crs) { - if (arg.crs.properties && arg.crs.properties.name === $data.GeometryBase.defaultCrs.properties.name) { - return new $data.GeometryPoint(arg); - } else { - return new $data.GeographyPoint(arg); - } - } else if(arg) { - if ('x' in arg && 'y' in arg) { - return new $data.GeometryPoint(arg.x, arg.y); - } else if ('longitude' in arg && 'latitude' in arg) { - return new $data.GeographyPoint(arg.longitude, arg.latitude); - } else if ('lng' in arg && 'lat' in arg) { - return new $data.GeographyPoint(arg.lng, arg.lat); - } - } -}; -/* $data.GeographyBase */ -$data.GeographyBase = function GeographyBase() { - $data.Geospatial.apply(this, arguments); - - this.crs = $data.GeographyBase.defaultCrs; - $data.GeographyBase.validateGeoJSON(this); -}; - -$data.GeographyBase.defaultCrs = { - properties: { - name: 'EPSG:4326' - }, - type: 'name' -}; - -$data.GeographyBase.parseFromString = function (strData) { - var lparenIdx = strData.indexOf('('); - if(lparenIdx >= 0){ - var name = strData.substring(0, lparenIdx).toLowerCase(); - var type = $data.GeographyBase.registered[name]; - - if (type && type.parseFromString && type != $data.GeographyBase) { - return type.parseFromString(strData); - } else { - Guard.raise(new Exception('parseFromString', 'Not Implemented', strData)); - } - } -}; -$data.GeographyBase.stringifyToUrl = function (geoData) { - if (geoData instanceof $data.GeographyBase && geoData.constructor && geoData.constructor.stringifyToUrl) { - return geoData.constructor.stringifyToUrl(geoData); - } else if (geoData instanceof $data.GeographyBase && geoData.constructor && Array.isArray(geoData.constructor.validMembers) && geoData.constructor.validMembers[0] === 'coordinates') { - var data = "geography'" + geoData.type.toUpperCase() + '('; - function buildArray(d, context) { - if (Array.isArray(d[0])) { - - for (var i = 0; i < d.length; i++) { - if (i > 0) data += ','; - if (Array.isArray(d[i][0])) - data += '('; - - buildArray(d[i]); - - if (Array.isArray(d[i][0])) - data += ')'; - } - - } else { - data += d.join(' '); - } - } - buildArray(geoData.coordinates, data); - - data += ")'"; - return data; - } else { - Guard.raise(new Exception('stringifyToUrl on instance type', 'Not Implemented', geoData)); - } -}; -$data.GeographyBase.registerType = function (name, type, base) { - $data.SimpleBase.registerType(name, type, base || $data.GeographyBase); - - $data.GeographyBase.registered = $data.GeographyBase.registered || {}; - $data.GeographyBase.registered[name.toLowerCase()] = type; -}; -$data.GeographyBase.validateGeoJSON = function (geoData) { - var type = geoData.type; - if (type) { - var geoType = $data.GeographyBase.registered[type.toLowerCase()]; - if (typeof geoType.validateGeoJSON === 'function') { - var isValid = geoType.validateGeoJSON(geoData); - if (isValid) { - return isValid; - } else { - Guard.raise(new Exception("Invalid '" + type + "' format!", 'Format Exception', geoData)); - } - } - } - console.log('GeoJSON validation missing', geoData); - return; -}; -$data.SimpleBase.registerType('GeographyBase', $data.GeographyBase, $data.Geospatial); -$data.Container.registerType(['$data.GeographyBase'], $data.GeographyBase); - -/* $data.GeographyPoint */ -$data.GeographyPoint = function GeographyPoint(lon, lat) { - if (lon && typeof lon === 'object' && Array.isArray(lon)) { - $data.GeographyBase.call(this, { coordinates: lon }); - } else if (lon && typeof lon === 'object' && ('longitude' in lon || 'latitude' in lon)) { - $data.GeographyBase.call(this, { coordinates: [lon.longitude, lon.latitude] }); - } else if (lon && typeof lon === 'object' && ('lng' in lon || 'lat' in lon)) { - $data.GeographyBase.call(this, { coordinates: [lon.lng, lon.lat] }); - } else if (lon && typeof lon === 'object') { - $data.GeographyBase.call(this, lon); - } else { - $data.GeographyBase.call(this, { coordinates: [lon || 0, lat || 0] }); - } -}; -$data.GeographyPoint.validateGeoJSON = function (geoData) { - return geoData && - Array.isArray(geoData.coordinates) && - geoData.coordinates.length == 2 && - typeof geoData.coordinates[0] === 'number' && - typeof geoData.coordinates[1] === 'number'; -}; -$data.GeographyPoint.parseFromString = function (strData) { - var data = strData.substring(strData.indexOf('(') + 1, strData.lastIndexOf(')')); - var values = data.split(' '); - - return new $data.GeographyPoint(parseFloat(values[0]), parseFloat(values[1])); -}; -$data.GeographyPoint.validMembers = ['coordinates']; -$data.GeographyBase.registerType('Point', $data.GeographyPoint); -Object.defineProperty($data.GeographyPoint.prototype, 'longitude', { get: function () { return this.coordinates[0]; }, set: function (v) { this.coordinates[0] = v; } }); -Object.defineProperty($data.GeographyPoint.prototype, 'latitude', { get: function () { return this.coordinates[1]; }, set: function (v) { this.coordinates[1] = v; } }); -$data.Container.registerType(['$data.GeographyPoint', 'GeographyPoint', '$data.Geography', 'Geography', 'geography', 'geo'], $data.GeographyPoint); -$data.Geography = $data.GeographyPoint; - -/* $data.GeographyLineString */ -$data.GeographyLineString = function GeographyLineString(data) { - if (Array.isArray(data)) { - $data.GeographyBase.call(this, { coordinates: data }); - } else { - $data.GeographyBase.call(this, data); - } -}; -$data.GeographyLineString.validateGeoJSON = function (geoData) { - var isValid = geoData && - Array.isArray(geoData.coordinates); - - for (var i = 0; isValid && i < geoData.coordinates.length; i++) { - var point = geoData.coordinates[i]; - isValid = isValid && - Array.isArray(point) && - point.length == 2 && - typeof point[0] === 'number' && - typeof point[1] === 'number'; - } - - return isValid; -}; -$data.GeographyLineString.validMembers = ['coordinates']; -$data.GeographyBase.registerType('LineString', $data.GeographyLineString); -$data.Container.registerType(['$data.GeographyLineString', 'GeographyLineString'], $data.GeographyLineString); - -/* $data.GeographyPolygon */ -$data.GeographyPolygon = function GeographyPolygon(data) { - if (typeof data === 'object' && (('topLeft' in data && 'bottomRight' in data) || ('topRight' in data && 'bottomLeft' in data))) { - var tl, tr, bl, br; - - if ('topLeft' in data && 'bottomRight' in data) { - tl = data.topLeft instanceof $data.GeographyPoint ? data.topLeft : new $data.GeographyPoint(data.topLeft); - br = data.bottomRight instanceof $data.GeographyPoint ? data.bottomRight : new $data.GeographyPoint(data.bottomRight); - tr = new $data.GeographyPoint([br.coordinates[0], tl.coordinates[1]]); - bl = new $data.GeographyPoint([tl.coordinates[0], br.coordinates[1]]); - } else { - tr = data.topRight instanceof $data.GeographyPoint ? data.topRight : new $data.GeographyPoint(data.topRight); - bl = data.bottomLeft instanceof $data.GeographyPoint ? data.bottomLeft : new $data.GeographyPoint(data.bottomLeft); - tl = new $data.GeographyPoint([bl.coordinates[0], tr.coordinates[1]]); - br = new $data.GeographyPoint([tr.coordinates[0], bl.coordinates[1]]); - } - - var coordinates = []; - coordinates.push([].concat(tl.coordinates)); - coordinates.push([].concat(tr.coordinates)); - coordinates.push([].concat(br.coordinates)); - coordinates.push([].concat(bl.coordinates)); - coordinates.push([].concat(tl.coordinates)); - - $data.GeographyBase.call(this, { coordinates: [coordinates] }); - - }else if (Array.isArray(data)) { - $data.GeographyBase.call(this, { coordinates: data }); - } else { - $data.GeographyBase.call(this, data); - } -}; -$data.GeographyPolygon.validateGeoJSON = function (geoData) { - var isValid = geoData && - Array.isArray(geoData.coordinates); - - for (var i = 0; isValid && i < geoData.coordinates.length; i++) { - var polygon = geoData.coordinates[i]; - var isValid = isValid && Array.isArray(polygon); - - for (var j = 0; isValid && j < polygon.length; j++) { - var point = polygon[j]; - - isValid = isValid && - Array.isArray(point) && - point.length == 2 && - typeof point[0] === 'number' && - typeof point[1] === 'number'; - } - } - - return isValid; -}; -$data.GeographyPolygon.parseFromString = function (strData) { - var data = strData.substring(strData.indexOf('(') + 1, strData.lastIndexOf(')')); - var rings = data.substring(data.indexOf('(') + 1, data.lastIndexOf(')')).split('),('); - - var data = []; - for (var i = 0; i < rings.length; i++) { - var polyPoints = []; - var pairs = rings[i].split(','); - for (var j = 0; j < pairs.length; j++) { - var values = pairs[j].split(' '); - - polyPoints.push([parseFloat(values[0]), parseFloat(values[1])]); - } - data.push(polyPoints); - } - - return new $data.GeographyPolygon(data); -}; -$data.GeographyPolygon.validMembers = ['coordinates']; -$data.GeographyBase.registerType('Polygon', $data.GeographyPolygon); -$data.Container.registerType(['$data.GeographyPolygon', 'GeographyPolygon'], $data.GeographyPolygon); - -/* $data.GeographyMultiPoint */ -$data.GeographyMultiPoint = function GeographyMultiPoint(data) { - if (Array.isArray(data)) { - $data.GeographyBase.call(this, { coordinates: data }); - } else { - $data.GeographyBase.call(this, data); - } -}; -$data.GeographyMultiPoint.validateGeoJSON = function (geoData) { - var isValid = geoData && - Array.isArray(geoData.coordinates); - - for (var i = 0; isValid && i < geoData.coordinates.length; i++) { - var point = geoData.coordinates[i]; - isValid = isValid && - Array.isArray(point) && - point.length == 2 && - typeof point[0] === 'number' && - typeof point[1] === 'number'; - } - - return isValid; -}; -$data.GeographyMultiPoint.validMembers = ['coordinates']; -$data.GeographyBase.registerType('MultiPoint', $data.GeographyMultiPoint); -$data.Container.registerType(['$data.GeographyMultiPoint', 'GeographyMultiPoint'], $data.GeographyMultiPoint); - -/* $data.GeographyMultiLineString */ -$data.GeographyMultiLineString = function GeographyMultiLineString(data) { - if (Array.isArray(data)) { - $data.GeographyBase.call(this, { coordinates: data }); - } else { - $data.GeographyBase.call(this, data); - } -}; -$data.GeographyMultiLineString.validateGeoJSON = function (geoData) { - var isValid = geoData && - Array.isArray(geoData.coordinates); - - for (var i = 0; isValid && i < geoData.coordinates.length; i++) { - var polygon = geoData.coordinates[i]; - var isValid = isValid && Array.isArray(polygon); - - for (var j = 0; isValid && j < polygon.length; j++) { - var point = polygon[j]; - - isValid = isValid && - Array.isArray(point) && - point.length == 2 && - typeof point[0] === 'number' && - typeof point[1] === 'number'; - } - } - - return isValid; -}; -$data.GeographyMultiLineString.validMembers = ['coordinates']; -$data.GeographyBase.registerType('MultiLineString', $data.GeographyMultiLineString); -$data.Container.registerType(['$data.GeographyMultiLineString', 'GeographyMultiLineString'], $data.GeographyMultiLineString); - -/* $data.GeographyMultiPolygon */ -$data.GeographyMultiPolygon = function GeographyMultiPolygon(data) { - if (Array.isArray(data)) { - $data.GeographyBase.call(this, { coordinates: data }); - } else { - $data.GeographyBase.call(this, data); - } -}; -$data.GeographyMultiPolygon.validateGeoJSON = function (geoData) { - var isValid = geoData && - Array.isArray(geoData.coordinates); - - for (var k = 0; isValid && k < geoData.coordinates.length; k++) { - var polygons = geoData.coordinates[k]; - var isValid = isValid && Array.isArray(polygons); - - for (var i = 0; isValid && i < polygons.length; i++) { - var polygon = polygons[i]; - var isValid = isValid && Array.isArray(polygon); - - for (var j = 0; isValid && j < polygon.length; j++) { - var point = polygon[j]; - - isValid = isValid && - Array.isArray(point) && - point.length == 2 && - typeof point[0] === 'number' && - typeof point[1] === 'number'; - } - } - } - - return isValid; -}; -$data.GeographyMultiPolygon.validMembers = ['coordinates']; -$data.GeographyBase.registerType('MultiPolygon', $data.GeographyMultiPolygon); -$data.Container.registerType(['$data.GeographyMultiPolygon', 'GeographyMultiPolygon'], $data.GeographyMultiPolygon); - -/* $data.GeographyCollection */ -$data.GeographyCollection = function GeographyCollection(data) { - if (Array.isArray(data)) { - $data.GeographyBase.call(this, { geometries: data }); - } else { - $data.GeographyBase.call(this, data); - } -}; -$data.GeographyCollection.validateGeoJSON = function (geoData) { - var isValid = geoData && - Array.isArray(geoData.geometries); - - for (var i = 0; isValid && i < geoData.geometries.length; i++) { - var geometry = geoData.geometries[i]; - try { - isValid = isValid && $data.GeographyBase.validateGeoJSON(geometry); - } catch (e) { - isValid = false; - } - } - - return isValid; -}; -$data.GeographyCollection.validMembers = ['geometries']; -$data.GeographyBase.registerType('GeometryCollection', $data.GeographyCollection); -$data.Container.registerType(['$data.GeographyCollection', 'GeographyCollection'], $data.GeographyCollection); - - -/* converters */ -$data.Container.registerConverter($data.GeographyPoint, $data.Object, function (value) { - return value ? new $data.GeographyPoint(value) : value; -}); -$data.Container.registerConverter($data.GeographyLineString, $data.Object, function (value) { - return value ? new $data.GeographyLineString(value) : value; -}); -$data.Container.registerConverter($data.GeographyPolygon, $data.Object, function (value) { - return value ? new $data.GeographyPolygon(value) : value; -}); -$data.Container.registerConverter($data.GeographyMultiPoint, $data.Object, function (value) { - return value ? new $data.GeographyMultiPoint(value) : value; -}); -$data.Container.registerConverter($data.GeographyMultiLineString, $data.Object, function (value) { - return value ? new $data.GeographyMultiLineString(value) : value; -}); -$data.Container.registerConverter($data.GeographyMultiPolygon, $data.Object, function (value) { - return value ? new $data.GeographyMultiPolygon(value) : value; -}); -$data.Container.registerConverter($data.GeographyCollection, $data.Object, function (value) { - return value ? new $data.GeographyCollection(value) : value; -}); -/* $data.Geometry */ -$data.GeometryBase = function GeometryBase() { - $data.Geospatial.apply(this, arguments); - - this.crs = $data.GeometryBase.defaultCrs; - $data.GeometryBase.validateGeoJSON(this); -}; - -$data.GeometryBase.defaultCrs = { - properties: { - name: 'EPSG:0' - }, - type: 'name' -}; - -$data.GeometryBase.parseFromString = function (strData) { - var lparenIdx = strData.indexOf('('); - if (lparenIdx >= 0) { - var name = strData.substring(0, lparenIdx).toLowerCase(); - var type = $data.GeometryBase.registered[name]; - - if (type && type.parseFromString && type != $data.GeometryBase) { - return type.parseFromString(strData); - } else { - Guard.raise(new Exception('parseFromString', 'Not Implemented', strData)); - } - } -}; -$data.GeometryBase.stringifyToUrl = function (geoData) { - if (geoData instanceof $data.GeometryBase && geoData.constructor && geoData.constructor.stringifyToUrl) { - return geoData.constructor.stringifyToUrl(geoData); - } else if (geoData instanceof $data.GeometryBase && geoData.constructor && Array.isArray(geoData.constructor.validMembers) && geoData.constructor.validMembers[0] === 'coordinates') { - var data = "geometry'" + geoData.type.toUpperCase() + '('; - function buildArray(d, context) { - if (Array.isArray(d[0])) { - - for (var i = 0; i < d.length; i++) { - if (i > 0) data += ','; - if (Array.isArray(d[i][0])) - data += '('; - - buildArray(d[i]); - - if (Array.isArray(d[i][0])) - data += ')'; - } - - } else { - data += d.join(' '); - } - } - buildArray(geoData.coordinates, data); - - data += ")'"; - return data; - } else { - Guard.raise(new Exception('stringifyToUrl on instance type', 'Not Implemented', geoData)); - } -}; -$data.GeometryBase.registerType = function (name, type, base) { - $data.SimpleBase.registerType(name, type, base || $data.GeometryBase); - - $data.GeometryBase.registered = $data.GeometryBase.registered || {}; - $data.GeometryBase.registered[name.toLowerCase()] = type; -}; -$data.GeometryBase.validateGeoJSON = function (geoData) { - var type = geoData.type; - if (type) { - var geoType = $data.GeometryBase.registered[type.toLowerCase()]; - if (typeof geoType.validateGeoJSON === 'function') { - var isValid = geoType.validateGeoJSON(geoData); - if (isValid) { - return isValid; - } else { - Guard.raise(new Exception("Invalid '" + type + "' format!", 'Format Exception', geoData)); - } - } - } - console.log('GeoJSON validation missing', geoData); - return; -}; -$data.SimpleBase.registerType('GeometryBase', $data.GeometryBase, $data.Geospatial); -$data.Container.registerType(['$data.GeometryBase'], $data.GeometryBase); - -/* $data.GeometryPoint */ -$data.GeometryPoint = function GeometryPoint(x, y) { - var param = x; - if (param && typeof param === 'object' && Array.isArray(param)) { - $data.GeometryBase.call(this, { coordinates: param }); - } else if (param && typeof param === 'object' && ('x' in param || 'y' in param)) { - $data.GeometryBase.call(this, { coordinates: [param.x, param.y] }); - } else if (param && typeof param === 'object') { - $data.GeometryBase.call(this, param); - } else { - $data.GeometryBase.call(this, { coordinates: [x || 0, y || 0] }); - } -}; -$data.GeometryPoint.validateGeoJSON = function (geoData) { - return geoData && - Array.isArray(geoData.coordinates) && - geoData.coordinates.length == 2 && - typeof geoData.coordinates[0] === 'number' && - typeof geoData.coordinates[1] === 'number'; -}; -$data.GeometryPoint.parseFromString = function (strData) { - var data = strData.substring(strData.indexOf('(') + 1, strData.lastIndexOf(')')); - var values = data.split(' '); - - return new $data.GeometryPoint(parseFloat(values[0]), parseFloat(values[1])); -}; -$data.GeometryPoint.validMembers = ['coordinates']; -$data.GeometryBase.registerType('Point', $data.GeometryPoint); -Object.defineProperty($data.GeometryPoint.prototype, 'x', { get: function () { return this.coordinates[0]; }, set: function (v) { this.coordinates[0] = v; } }); -Object.defineProperty($data.GeometryPoint.prototype, 'y', { get: function () { return this.coordinates[1]; }, set: function (v) { this.coordinates[1] = v; } }); -$data.Container.registerType(['$data.GeometryPoint', 'GeometryPoint'], $data.GeometryPoint); - -/* $data.GeometryLineString */ -$data.GeometryLineString = function GeometryLineString(data) { - if (Array.isArray(data)) { - $data.GeometryBase.call(this, { coordinates: data }); - } else { - $data.GeometryBase.call(this, data); - } -}; -$data.GeometryLineString.validateGeoJSON = function (geoData) { - var isValid = geoData && - Array.isArray(geoData.coordinates); - - for (var i = 0; isValid && i < geoData.coordinates.length; i++) { - var point = geoData.coordinates[i]; - isValid = isValid && - Array.isArray(point) && - point.length == 2 && - typeof point[0] === 'number' && - typeof point[1] === 'number'; - } - - return isValid; -}; -$data.GeometryLineString.validMembers = ['coordinates']; -$data.GeometryBase.registerType('LineString', $data.GeometryLineString); -$data.Container.registerType(['$data.GeometryLineString', 'GeometryLineString'], $data.GeometryLineString); - -/* $data.GeometryPolygon */ -$data.GeometryPolygon = function GeometryPolygon(data) { - if (typeof data === 'object' && (('topLeft' in data && 'bottomRight' in data) || ('topRight' in data && 'bottomLeft' in data))) { - var tl, tr, bl, br; - - if ('topLeft' in data && 'bottomRight' in data) { - tl = data.topLeft instanceof $data.GeometryPoint ? data.topLeft : new $data.GeometryPoint(data.topLeft); - br = data.bottomRight instanceof $data.GeometryPoint ? data.bottomRight : new $data.GeometryPoint(data.bottomRight); - tr = new $data.GeometryPoint([br.coordinates[0], tl.coordinates[1]]); - bl = new $data.GeometryPoint([tl.coordinates[0], br.coordinates[1]]); - } else { - tr = data.topRight instanceof $data.GeometryPoint ? data.topRight : new $data.GeometryPoint(data.topRight); - bl = data.bottomLeft instanceof $data.GeometryPoint ? data.bottomLeft : new $data.GeometryPoint(data.bottomLeft); - tl = new $data.GeometryPoint([bl.coordinates[0], tr.coordinates[1]]); - br = new $data.GeometryPoint([tr.coordinates[0], bl.coordinates[1]]); - } - - var coordinates = []; - coordinates.push([].concat(tl.coordinates)); - coordinates.push([].concat(tr.coordinates)); - coordinates.push([].concat(br.coordinates)); - coordinates.push([].concat(bl.coordinates)); - coordinates.push([].concat(tl.coordinates)); - - $data.GeometryBase.call(this, { coordinates: [coordinates] }); - - }else if (Array.isArray(data)) { - $data.GeometryBase.call(this, { coordinates: data }); - } else { - $data.GeometryBase.call(this, data); - } -}; -$data.GeometryPolygon.validateGeoJSON = function (geoData) { - var isValid = geoData && - Array.isArray(geoData.coordinates); - - for (var i = 0; isValid && i < geoData.coordinates.length; i++) { - var polygon = geoData.coordinates[i]; - var isValid = isValid && Array.isArray(polygon); - - for (var j = 0; isValid && j < polygon.length; j++) { - var point = polygon[j]; - - isValid = isValid && - Array.isArray(point) && - point.length == 2 && - typeof point[0] === 'number' && - typeof point[1] === 'number'; - } - } - - return isValid; -}; -$data.GeometryPolygon.parseFromString = function (strData) { - var data = strData.substring(strData.indexOf('(') + 1, strData.lastIndexOf(')')); - var rings = data.substring(data.indexOf('(') + 1, data.lastIndexOf(')')).split('),('); - - var data = []; - for (var i = 0; i < rings.length; i++) { - var polyPoints = []; - var pairs = rings[i].split(','); - for (var j = 0; j < pairs.length; j++) { - var values = pairs[j].split(' '); - - polyPoints.push([parseFloat(values[0]), parseFloat(values[1])]); - } - data.push(polyPoints); - } - - return new $data.GeometryPolygon(data); -}; -$data.GeometryPolygon.validMembers = ['coordinates']; -$data.GeometryBase.registerType('Polygon', $data.GeometryPolygon); -$data.Container.registerType(['$data.GeometryPolygon', 'GeometryPolygon'], $data.GeometryPolygon); - -/* $data.GeometryMultiPoint */ -$data.GeometryMultiPoint = function GeometryMultiPoint(data) { - if (Array.isArray(data)) { - $data.GeometryBase.call(this, { coordinates: data }); - } else { - $data.GeometryBase.call(this, data); - } -}; -$data.GeometryMultiPoint.validateGeoJSON = function (geoData) { - var isValid = geoData && - Array.isArray(geoData.coordinates); - - for (var i = 0; isValid && i < geoData.coordinates.length; i++) { - var point = geoData.coordinates[i]; - isValid = isValid && - Array.isArray(point) && - point.length == 2 && - typeof point[0] === 'number' && - typeof point[1] === 'number'; - } - - return isValid; -}; -$data.GeometryMultiPoint.validMembers = ['coordinates']; -$data.GeometryBase.registerType('MultiPoint', $data.GeometryMultiPoint); -$data.Container.registerType(['$data.GeometryMultiPoint', 'GeometryMultiPoint'], $data.GeometryMultiPoint); - -/* $data.GeometryMultiLineString */ -$data.GeometryMultiLineString = function GeometryMultiLineString(data) { - if (Array.isArray(data)) { - $data.GeometryBase.call(this, { coordinates: data }); - } else { - $data.GeometryBase.call(this, data); - } -}; -$data.GeometryMultiLineString.validateGeoJSON = function (geoData) { - var isValid = geoData && - Array.isArray(geoData.coordinates); - - for (var i = 0; isValid && i < geoData.coordinates.length; i++) { - var polygon = geoData.coordinates[i]; - var isValid = isValid && Array.isArray(polygon); - - for (var j = 0; isValid && j < polygon.length; j++) { - var point = polygon[j]; - - isValid = isValid && - Array.isArray(point) && - point.length == 2 && - typeof point[0] === 'number' && - typeof point[1] === 'number'; - } - } - - return isValid; -}; -$data.GeometryMultiLineString.validMembers = ['coordinates']; -$data.GeometryBase.registerType('MultiLineString', $data.GeometryMultiLineString); -$data.Container.registerType(['$data.GeometryMultiLineString', 'GeometryMultiLineString'], $data.GeometryMultiLineString); - -/* $data.GeometryMultiPolygon */ -$data.GeometryMultiPolygon = function GeometryMultiPolygon(data) { - if (Array.isArray(data)) { - $data.GeometryBase.call(this, { coordinates: data }); - } else { - $data.GeometryBase.call(this, data); - } -}; -$data.GeometryMultiPolygon.validateGeoJSON = function (geoData) { - var isValid = geoData && - Array.isArray(geoData.coordinates); - - for (var k = 0; isValid && k < geoData.coordinates.length; k++) { - var polygons = geoData.coordinates[k]; - var isValid = isValid && Array.isArray(polygons); - - for (var i = 0; isValid && i < polygons.length; i++) { - var polygon = polygons[i]; - var isValid = isValid && Array.isArray(polygon); - - for (var j = 0; isValid && j < polygon.length; j++) { - var point = polygon[j]; - - isValid = isValid && - Array.isArray(point) && - point.length == 2 && - typeof point[0] === 'number' && - typeof point[1] === 'number'; - } - } - } - - return isValid; -}; -$data.GeometryMultiPolygon.validMembers = ['coordinates']; -$data.GeometryBase.registerType('MultiPolygon', $data.GeometryMultiPolygon); -$data.Container.registerType(['$data.GeometryMultiPolygon', 'GeometryMultiPolygon'], $data.GeometryMultiPolygon); - -/* $data.GeometryCollection */ -$data.GeometryCollection = function GeometryCollection(data) { - if (Array.isArray(data)) { - $data.GeometryBase.call(this, { geometries: data }); - } else { - $data.GeometryBase.call(this, data); - } -}; -$data.GeometryCollection.validateGeoJSON = function (geoData) { - var isValid = geoData && - Array.isArray(geoData.geometries); - - for (var i = 0; isValid && i < geoData.geometries.length; i++) { - var geometry = geoData.geometries[i]; - try { - isValid = isValid && $data.GeometryBase.validateGeoJSON(geometry); - } catch (e) { - isValid = false; - } - } - - return isValid; -}; -$data.GeometryCollection.validMembers = ['geometries']; -$data.GeometryBase.registerType('GeometryCollection', $data.GeometryCollection); -$data.Container.registerType(['$data.GeometryCollection', 'GeometryCollection'], $data.GeometryCollection); - -/* converters */ -$data.Container.registerConverter($data.GeometryPoint, $data.Object, function (value) { - return value ? new $data.GeometryPoint(value) : value; -}); -$data.Container.registerConverter($data.GeometryLineString, $data.Object, function (value) { - return value ? new $data.GeometryLineString(value) : value; -}); -$data.Container.registerConverter($data.GeometryPolygon, $data.Object, function (value) { - return value ? new $data.GeometryPolygon(value) : value; -}); -$data.Container.registerConverter($data.GeometryMultiPoint, $data.Object, function (value) { - return value ? new $data.GeometryMultiPoint(value) : value; -}); -$data.Container.registerConverter($data.GeometryMultiLineString, $data.Object, function (value) { - return value ? new $data.GeometryMultiLineString(value) : value; -}); -$data.Container.registerConverter($data.GeometryMultiPolygon, $data.Object, function (value) { - return value ? new $data.GeometryMultiPolygon(value) : value; -}); -$data.Container.registerConverter($data.GeometryCollection, $data.Object, function (value) { - return value ? new $data.GeometryCollection(value) : value; -});$data.Guid = function Guid(value) { - /// - - if (value === undefined || (typeof value === 'string' && /^[a-zA-z0-9]{8}-[a-zA-z0-9]{4}-[a-zA-z0-9]{4}-[a-zA-z0-9]{4}-[a-zA-z0-9]{12}$/.test(value))) { - this.value = value || '00000000-0000-0000-0000-000000000000'; - } else { - throw Guard.raise(new Exception('TypeError: ', 'value not convertable to $data.Guid', value)); - } -}; -$data.Container.registerType(['$data.Guid', 'Guid', 'guid'], $data.Guid); -$data.Container.registerConverter('$data.Guid', { - '$data.String': function (value) { - return value ? $data.parseGuid(value).toString() : value; - }, - '$data.Guid': function (value) { - return value ? value.toString() : value; - } -}, { - '$data.String': function (value) { - return value ? value.toString() : value; - } -}); - - -$data.Guid.prototype.toJSON = function () { - return this.value; -}; - -$data.Guid.prototype.valueOf = function () { - return this.value; -}; - -$data.Guid.prototype.toString = function () { - return this.value; -}; - -$data.Guid.NewGuid = function () { - return $data.createGuid(); -}; - -$data.parseGuid = function (guid) { - return new $data.Guid(guid); -}; - -(function () { - /*! - Math.uuid.js (v1.4) - http://www.broofa.com - mailto:robert@broofa.com - - Copyright (c) 2010 Robert Kieffer - Dual licensed under the MIT and GPL licenses. - */ - - var CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''); - - $data.createGuid = function (guidString) { - if (guidString) { - return new $data.Guid(guidString); - }; - - var len; - var chars = CHARS, uuid = [], i; - var radix = chars.length; - - if (len) { - // Compact form - for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix]; - } else { - // rfc4122, version 4 form - var r; - - // rfc4122 requires these characters - uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'; - uuid[14] = '4'; - - // Fill in random data. At i==19 set the high bits of clock sequence as - // per rfc4122, sec. 4.1.5 - for (i = 0; i < 36; i++) { - if (!uuid[i]) { - r = 0 | Math.random() * 16; - uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]; - } - } - } - - return $data.parseGuid(uuid.join('')); - }; -})();$data.Blob = function Blob(){}; - -$data.Blob.createFromHexString = function(value){ - if (value != value.match(new RegExp('[0-9a-fA-F]+'))[0]){ - Guard.raise(new Exception('TypeError: ', 'value not convertable to $data.Blob', value)); - }else{ - //if (value.length & 1) value = '0' + value; - var arr = new (typeof Buffer != 'undefined' ? Buffer : Uint8Array)(value.length >> 1); - for (var i = 0, j = 1, k = 0; i < value.length; i += 2, j += 2, k++) { - arr[k] = parseInt('0x' + value[i] + value[j], 16); - } - - return arr; - } -}; - -$data.Blob.toString = function(value){ - if (!value || !value.length) return null; - var s = ''; - for (var i = 0; i < value.length; i++){ - s += String.fromCharCode(value[i]); - } - - return s; -}; - -$data.Blob.toBase64 = function(value){ - if (!value || !value.length) return null; - return btoa($data.Blob.toString(value)); -}; - -$data.Blob.toArray = function(src){ - if (!src || !src.length) return null; - var arr = new Array(src.length); - for (var i = 0; i < src.length; i++){ - arr[i] = src[i]; - } - - return arr; -}; - -/*$data.Blob.toJSON = function(value){ - return JSON.stringify($data.Blob.toArray(value)); -};*/ - -$data.Blob.toHexString = function(value){ - if (!value || !value.length) return null; - var s = ''; - for (var i = 0; i < value.length; i++){ - s += ('00' + value[i].toString(16)).slice(-2); - } - - return s.toUpperCase(); -}; - -$data.Blob.toDataURL = function(value){ - if (!value || !value.length) return null; - return 'data:application/octet-stream;base64,' + btoa($data.Blob.toString(value)); -}; - -$data.Container.registerType(["$data.Blob", "blob", "JayBlob"], $data.Blob); -$data.Container.registerConverter('$data.Blob',{ - '$data.String': function (value){ - if (value && value.length){ - var blob = new (typeof Buffer !== 'undefined' ? Buffer : Uint8Array)(value.length); - for (var i = 0; i < value.length; i++){ - blob[i] = value.charCodeAt(i); - } - - return blob; - }else return null; - }, - '$data.Array': function(value){ - return new (typeof Buffer !== 'undefined' ? Buffer : Uint8Array)(value); - }, - '$data.Number': function(value){ - return new (typeof Buffer !== 'undefined' ? Buffer : Uint8Array)($data.packIEEE754(value, 11, 52).reverse()); - }, - '$data.Boolean': function(value){ - return new (typeof Buffer !== 'undefined' ? Buffer : Uint8Array)([value | 0]); - }, - 'default': function(value){ - if (typeof Blob !== 'undefined' && value instanceof Blob){ - var req = new XMLHttpRequest(); - req.open('GET', URL.createObjectURL(value), false); - req.responseType = 'arraybuffer'; - req.send(null); - return $data.Container.convertTo(req.response, $data.Blob); - } else if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { - return new (typeof Buffer !== 'undefined' ? Buffer : Uint8Array)(new Uint8Array(value)); - }else if (value instanceof Uint8Array){ - if (typeof Buffer !== 'undefined') return new Buffer(value); - else return value; - }else if (typeof Buffer !== 'undefined' ? value instanceof Buffer : false){ - return value; - }else if (value.buffer){ - return new (typeof Buffer !== 'undefined' ? Buffer : Uint8Array)(value); - }else if (typeof value == 'object' && value instanceof Object){ - var arr = []; - for (var i in value){ - arr[i] = value[i]; - } - if (!arr.length) throw 0; - return new (typeof Buffer !== 'undefined' ? Buffer : Uint8Array)(arr); - } - throw 0; - } -}, { - '$data.String': function(value){ - return $data.Blob.toString(value); - }, - '$data.Array': function(value){ - return $data.Blob.toArray(value); - } -}); -(function ($data) { - - function Edm_Boolean() { }; - $data.Container.registerType('Edm.Boolean', Edm_Boolean); - $data.Container.mapType(Edm_Boolean, $data.Boolean); - - function Edm_Binary() { }; - $data.Container.registerType('Edm.Binary', Edm_Binary); - $data.Container.mapType(Edm_Binary, $data.Blob); - - function Edm_DateTime() { }; - $data.Container.registerType('Edm.DateTime', Edm_DateTime); - $data.Container.mapType(Edm_DateTime, $data.Date); - - function Edm_DateTimeOffset() { }; - $data.Container.registerType('Edm.DateTimeOffset', Edm_DateTimeOffset); - $data.Container.mapType(Edm_DateTimeOffset, $data.DateTimeOffset); - - function Edm_Time() { }; - $data.Container.registerType('Edm.Time', Edm_Time); - $data.Container.mapType(Edm_Time, $data.Time); - - function Edm_Decimal() { }; - $data.Container.registerType('Edm.Decimal', Edm_Decimal); - $data.Container.mapType(Edm_Decimal, $data.Decimal); - - function Edm_Float() { }; - $data.Container.registerType('Edm.Float', Edm_Float); - $data.Container.mapType(Edm_Float, $data.Float); - - function Edm_Single() { }; - $data.Container.registerType('Edm.Single', Edm_Single); - $data.Container.mapType(Edm_Single, $data.Float); - - function Edm_Double() { }; - $data.Container.registerType('Edm.Double', Edm_Double); - $data.Container.mapType(Edm_Double, $data.Number); - - function Edm_Guid() { }; - $data.Container.registerType('Edm.Guid', Edm_Guid); - $data.Container.mapType(Edm_Guid, $data.Guid); - - function Edm_Int16() { }; - $data.Container.registerType('Edm.Int16', Edm_Int16); - $data.Container.mapType(Edm_Int16, $data.Int16); - - function Edm_Int32() { }; - $data.Container.registerType('Edm.Int32', Edm_Int32); - $data.Container.mapType(Edm_Int32, $data.Integer); - - function Edm_Int64() { }; - $data.Container.registerType('Edm.Int64', Edm_Int64); - $data.Container.mapType(Edm_Int64, $data.Int64); - - function Edm_Byte() { }; - $data.Container.registerType('Edm.Byte', Edm_Byte); - $data.Container.mapType(Edm_Byte, $data.Byte); - - function Edm_SByte() { }; - $data.Container.registerType('Edm.SByte', Edm_SByte); - $data.Container.mapType(Edm_SByte, $data.SByte); - - function Edm_String() { }; - $data.Container.registerType('Edm.String', Edm_String); - $data.Container.mapType(Edm_String, $data.String); - - function Edm_GeographyPoint() { }; - $data.Container.registerType('Edm.GeographyPoint', Edm_GeographyPoint); - $data.Container.mapType(Edm_GeographyPoint, $data.GeographyPoint); - - function Edm_GeographyLineString() { }; - $data.Container.registerType('Edm.GeographyLineString', Edm_GeographyLineString); - $data.Container.mapType(Edm_GeographyLineString, $data.GeographyLineString); - - function Edm_GeographyPolygon() { }; - $data.Container.registerType('Edm.GeographyPolygon', Edm_GeographyPolygon); - $data.Container.mapType(Edm_GeographyPolygon, $data.GeographyPolygon); - - function Edm_GeographyMultiPoint() { }; - $data.Container.registerType('Edm.GeographyMultiPoint', Edm_GeographyMultiPoint); - $data.Container.mapType(Edm_GeographyMultiPoint, $data.GeographyMultiPoint); - - function Edm_GeographyMultiLineString() { }; - $data.Container.registerType('Edm.GeographyMultiLineString', Edm_GeographyMultiLineString); - $data.Container.mapType(Edm_GeographyMultiLineString, $data.GeographyMultiLineString); - - function Edm_GeographyMultiPolygon() { }; - $data.Container.registerType('Edm.GeographyMultiPolygon', Edm_GeographyMultiPolygon); - $data.Container.mapType(Edm_GeographyMultiPolygon, $data.GeographyMultiPolygon); - - function Edm_GeographyCollection() { }; - $data.Container.registerType('Edm.GeographyCollection', Edm_GeographyCollection); - $data.Container.mapType(Edm_GeographyCollection, $data.GeographyCollection); - - function Edm_GeometryPoint() { }; - $data.Container.registerType('Edm.GeometryPoint', Edm_GeometryPoint); - $data.Container.mapType(Edm_GeometryPoint, $data.GeometryPoint); - - function Edm_GeometryLineString() { }; - $data.Container.registerType('Edm.GeometryLineString', Edm_GeometryLineString); - $data.Container.mapType(Edm_GeometryLineString, $data.GeometryLineString); - - function Edm_GeometryPolygon() { }; - $data.Container.registerType('Edm.GeometryPolygon', Edm_GeometryPolygon); - $data.Container.mapType(Edm_GeometryPolygon, $data.GeometryPolygon); - - function Edm_GeometryMultiPoint() { }; - $data.Container.registerType('Edm.GeometryMultiPoint', Edm_GeometryMultiPoint); - $data.Container.mapType(Edm_GeometryMultiPoint, $data.GeometryMultiPoint); - - function Edm_GeometryMultiLineString() { }; - $data.Container.registerType('Edm.GeometryMultiLineString', Edm_GeometryMultiLineString); - $data.Container.mapType(Edm_GeometryMultiLineString, $data.GeometryMultiLineString); - - function Edm_GeometryMultiPolygon() { }; - $data.Container.registerType('Edm.GeometryMultiPolygon', Edm_GeometryMultiPolygon); - $data.Container.mapType(Edm_GeometryMultiPolygon, $data.GeometryMultiPolygon); - - function Edm_GeometryCollection() { }; - $data.Container.registerType('Edm.GeometryCollection', Edm_GeometryCollection); - $data.Container.mapType(Edm_GeometryCollection, $data.GeometryCollection); - - $data.oDataEdmMapping = { - '$data.Byte': 'Edm.Byte', - '$data.SByte': 'Edm.SByte', - '$data.Decimal': 'Edm.Decimal', - '$data.Float': 'Edm.Float', - '$data.Int16': 'Edm.Int16', - '$data.Int64': 'Edm.Int64', - '$data.DateTimeOffset': 'Edm.DateTimeOffset', - '$data.Time': 'Edm.Time', - '$data.Boolean': 'Edm.Boolean', - '$data.Blob': 'Edm.Binary', - '$data.Date': 'Edm.DateTime', - '$data.Number': 'Edm.Double', - '$data.Integer': 'Edm.Int32', - '$data.Int32': 'Edm.Int32', - '$data.String': 'Edm.String', - '$data.ObjectID': 'Edm.String', - '$data.GeographyPoint': 'Edm.GeographyPoint', - '$data.GeographyLineString': 'Edm.GeographyLineString', - '$data.GeographyPolygon': 'Edm.GeographyPolygon', - '$data.GeographyMultiPoint': 'Edm.GeographyMultiPoint', - '$data.GeographyMultiLineString': 'Edm.GeographyMultiLineString', - '$data.GeographyMultiPolygon': 'Edm.GeographyMultiPolygon', - '$data.GeographyCollection': 'Edm.GeographyCollection', - '$data.GeometryPoint': 'Edm.GeometryPoint', - '$data.GeometryLineString': 'Edm.GeometryLineString', - '$data.GeometryPolygon': 'Edm.GeometryPolygon', - '$data.GeometryMultiPoint': 'Edm.GeometryMultiPoint', - '$data.GeometryMultiLineString': 'Edm.GeometryMultiLineString', - '$data.GeometryMultiPolygon': 'Edm.GeometryMultiPolygon', - '$data.GeometryCollection': 'Edm.GeometryCollection', - '$data.Guid': 'Edm.Guid' - }; - -})($data); -$data.Container.registerConverter('$data.Boolean', { - '$data.String': function(value){ - if (value.toLowerCase() == 'true') return true; - if (value.toLowerCase() == 'false') return false; - - return !!value; - }, - 'default': function(value){ - return !!value; - } -}); - -$data.Container.registerConverter('$data.Integer', { - 'default': function (value) { - if (value === Number.POSITIVE_INFINITY || - value === Number.NEGATIVE_INFINITY || - value === Number.MAX_VALUE || - value === Number.MIN_VALUE) { - return value; - } - - var r = parseInt(+value, 10); - if (isNaN(r)) throw 0; - return r; - } -}); - -$data.Container.registerConverter('$data.Int32', { - 'default': function (value) { - return value | 0; - } -}); - -$data.Container.registerConverter('$data.Number', { - 'default': function(value){ - var r = +value; - if (isNaN(r)) throw 0; - return r; - } -}); - -$data.Container.registerConverter('$data.Byte', { - 'default': function(value){ - return (value | 0) & 0xff; - } -}); - -$data.Container.registerConverter('$data.Date', { - 'default': function(value){ - var d = new Date(value); - if (isNaN(d)) throw 0; - return d; - } -}); - -$data.Container.registerConverter('$data.DateTimeOffset', { - '$data.Date': function(value){ - return value; - }, - 'default': function(value){ - var d = new Date(value); - if (isNaN(d)) throw 0; - return d; - } -}); -(function () { - function parseFromString(value) { - var regex = /^([0-9]|0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]|[0-9])(:([0-5][0-9]|[0-9])(\.(\d+))?)?$/; - - var matches = regex.exec(value) - if (!matches) throw 0; - var time = ''; - time += ('00' + matches[1]).slice(-2); - time += ':' + ('00' + matches[2]).slice(-2); - if (matches[4]) { - time += ':' + ('00' + matches[4]).slice(-2); - } else { - time += ':00'; - } - if (matches[6]) - time += '.' + (matches[6] + '000').slice(0, 3); - - return time; - } - - $data.Container.registerConverter('$data.Time', { - '$data.String': parseFromString, - '$data.Number': function tt(value) { - var metrics = [1000, 60, 60]; - var result = [0, 0, 0, value | 0]; - - for (var i = 0; i < metrics.length; i++) { - result[metrics.length - (i + 1)] = (result[metrics.length - i] / metrics[i]) | 0; - result[metrics.length - i] -= result[metrics.length - (i + 1)] * metrics[i]; - } - - var time = ''; - for (var i = 0; i < result.length; i++) { - if (i < result.length - 1) { - time += ('00' + result[i]).slice(-2); - if (i < result.length - 2) time += ':'; - } else { - time += '.' + ('000' + result[i]).slice(-3); - } - } - - return parseFromString(time); - }, - '$data.Date': function (value) { - var val = value.getHours() + ':' + value.getMinutes() + ':' + value.getSeconds(); - var ms = value.getMilliseconds() - if (ms) { - val += '.' + ms; - } - - return parseFromString(val); - } - }); -})(); - -$data.Container.registerConverter('$data.Decimal', { - '$data.Boolean': function(value){ - return value ? '1' : '0'; - }, - '$data.Number': function(value){ - return value.toString(); - }, - '$data.String': function(value){ - if (!/^\-?([0-9]+(\.[0-9]+)?|Infinity)$/.test(value)) throw 0; - return value; - }, - '$data.Date': function(value){ - var r = value.valueOf(); - if (isNaN(r)) throw 0; - return r.toString(); - } -}); - -$data.packIEEE754 = function(v, ebits, fbits){ - var bias = (1 << (ebits - 1)) - 1, s, e, f, ln, i, bits, str, bytes; - - // Compute sign, exponent, fraction - if (v !== v){ - // NaN - // http://dev.w3.org/2006/webapi/WebIDL/#es-type-mapping - e = (1 << bias) - 1; f = Math.pow(2, fbits - 1); s = 0; - }else if (v === Infinity || v === -Infinity){ - e = (1 << bias) - 1; f = 0; s = (v < 0) ? 1 : 0; - }else if (v === 0){ - e = 0; f = 0; s = (1 / v === -Infinity) ? 1 : 0; - }else{ - s = v < 0; - v = Math.abs(v); - - if (v >= Math.pow(2, 1 - bias)){ - // Normalized - ln = Math.min(Math.floor(Math.log(v) / Math.LN2), bias); - e = ln + bias; - f = Math.round(v * Math.pow(2, fbits - ln) - Math.pow(2, fbits)); - }else{ - // Denormalized - e = 0; - f = Math.round(v / Math.pow(2, 1 - bias - fbits)); - } - } - - // Pack sign, exponent, fraction - bits = []; - for (i = fbits; i; i -= 1) { bits.push(f % 2 ? 1 : 0); f = Math.floor(f / 2); } - for (i = ebits; i; i -= 1) { bits.push(e % 2 ? 1 : 0); e = Math.floor(e / 2); } - bits.push(s ? 1 : 0); - bits.reverse(); - str = bits.join(''); - - // Bits to bytes - bytes = []; - while (str.length){ - bytes.push(parseInt(str.substring(0, 8), 2)); - str = str.substring(8); - } - - return bytes; -}; - -$data.unpackIEEE754 = function(bytes, ebits, fbits){ - // Bytes to bits - var bits = [], i, j, b, str, bias, s, e, f; - - for (i = bytes.length; i; i -= 1){ - b = bytes[i - 1]; - for (j = 8; j; j -= 1){ - bits.push(b % 2 ? 1 : 0); b = b >> 1; - } - } - bits.reverse(); - str = bits.join(''); - - // Unpack sign, exponent, fraction - bias = (1 << (ebits - 1)) - 1; - s = parseInt(str.substring(0, 1), 2) ? -1 : 1; - e = parseInt(str.substring(1, 1 + ebits), 2); - f = parseInt(str.substring(1 + ebits), 2); - - // Produce number - if (e === (1 << ebits) - 1){ - return f !== 0 ? NaN : s * Infinity; - }else if (e > 0){ - // Normalized - return s * Math.pow(2, e - bias) * (1 + f / Math.pow(2, fbits)); - }else if (f !== 0){ - // Denormalized - return s * Math.pow(2, -(bias - 1)) * (f / Math.pow(2, fbits)); - }else{ - return s < 0 ? -0 : 0; - } -}; - -$data.IEEE754 = function(v, e, f){ - return $data.unpackIEEE754($data.packIEEE754(v, e, f), e, f); -}; - -$data.Container.registerConverter('$data.Float', { - 'default': function(value){ - var r = +value; - if (isNaN(r)) throw 0; - return $data.IEEE754(r, 8, 23); - } -}); - -$data.Container.registerConverter('$data.Int16', { - 'default': function(value){ - var r = (value | 0) & 0xffff; - if (r >= 0x8000) return r - 0x10000; - return r; - } -}); - -$data.Container.registerConverter('$data.Int64', { - '$data.Boolean': function(value){ - return value ? '1' : '0'; - }, - '$data.Number': function(value){ - var r = value.toString(); - if (r.indexOf('.') > 0) return r.split('.')[0]; - if (r.indexOf('.') == 0) throw 0; - return r; - }, - '$data.String': function(value){ - if (!/^\-?([0-9]+(\.[0-9]+)?|Infinity)$/.test(value)) throw 0; - if (value.indexOf('.') > 0) return value.split('.')[0]; - if (value.indexOf('.') == 0) throw 0; - return value; - }, - '$data.Date': function(value){ - var r = value.valueOf(); - if (isNaN(r)) throw 0; - return r.toString(); - } -}); - -$data.Container.registerConverter('$data.SByte', { - 'default': function(value){ - var r = (value | 0) & 0xff; - if (r >= 0x80) return r - 0x100; - return r; - } -}); - -$data.Container.registerConverter('$data.String', { - '$data.Date': function(value){ - return value.toISOString(); - }, - '$data.ObjectID': function(value){ - return btoa(value.toString()); - }, - 'default': function(value){ - if (typeof value === 'object') return JSON.stringify(value); - return value.toString(); - } -}); - -$data.Container.registerConverter('$data.Object', { - '$data.String': function(value){ - return JSON.parse(value); - }, - '$data.Function': function(){ - throw 0; - } -}); - -$data.Container.registerConverter('$data.Array', { - '$data.String': function(value){ - var r = JSON.parse(value); - if (!Array.isArray(r)) throw 0; - return r; - } -}); - -$data.Container.registerConverter('$data.ObjectID', { - '$data.ObjectID': function(value){ - try{ - return btoa(value.toString()); - }catch(e){ - return value; - } - }, - '$data.String': function(id){ - return id; - } -}); - -$data.Container.proxyConverter = function(v){ return v; }; -$data.Container.defaultConverter = function(type){ return function(v){ return $data.Container.convertTo(v, type); }; }; -$data.StringFunctions = { - startsWith: function () { - var self, str; - if (arguments.length == 2) { - self = arguments[0]; - str = arguments[1]; - } else if (arguments.length == 1 && typeof this === 'string') { - self = this; - str = arguments[0]; - } else if (this instanceof String) { - self = this.valueOf(); - str = arguments[0]; - } else - return false; - - if (typeof self !== 'string') return false; - return self.indexOf(str) === 0; - }, - endsWith: function () { - var self, str; - if (arguments.length == 2) { - self = arguments[0]; - str = arguments[1]; - } else if (arguments.length == 1 && typeof this === 'string') { - self = this; - str = arguments[0]; - } else if (this instanceof String) { - self = this.valueOf(); - str = arguments[0]; - } else - return false; - - if (typeof self !== 'string') return false; - return self.slice(-str.length) === str; - }, - contains: function () { - var self, str; - if (arguments.length == 2) { - self = arguments[0]; - str = arguments[1]; - } else if (arguments.length == 1 && typeof this === 'string') { - self = this; - str = arguments[0]; - } else if (this instanceof String) { - self = this.valueOf(); - str = arguments[0]; - } else - return false; - - if (typeof self !== 'string') return false; - return self.indexOf(str) >= 0; - } -}; -//TODO: Finish refactoring ExpressionNode.js - -$data.Class.define("$data.Expressions.ExpressionType", null, null, {}, { - Constant: "constant", // { type:LITERAL, executable:true, valueType:, value: } - Variable: "variable", // { type:VARIABLE, executable:true, name: } - MemberAccess: "memberAccess", // { type:MEMBERACCESS, executable:true, expression:, member: } - Call: "call", - - /* binary operators */ - Equal: "equal", - NotEqual: "notEqual", - EqualTyped: "equalTyped", - NotEqualTyped: "notEqualTyped", - GreaterThen: "greaterThan", - LessThen: "lessThan", - GreaterThenOrEqual: "greaterThanOrEqual", - LessThenOrEqual: "lessThenOrEqual", - Or: "or", - OrBitwise: "orBitwise", - And: "and", - AndBitwise: "andBitwise", - - - In: "in", - - Add: "add", - Divide: "divide", - Multiply: "multiply", - Subtract: "subtract", - Modulo: "modulo", - ArrayIndex: "arrayIndex", - - /* unary operators */ - New: "new", - Positive: "positive", - Negative: "negative", - Increment: "increment", - Decrement: "decrement", - Not: "not", - - - This: "this", - LambdaParameterReference: "lambdaParameterReference", - LambdaParameter: "lambdaParameter", - Parameter: "parameter", - - ArrayLiteral: "arrayLiteral", - ObjectLiteral: "objectLiteral", - ObjectField: "objectField", - Function: "Function", - Unknown: "UNKNOWN", - - EntitySet: "EntitySet", - ServiceOperation: "ServiceOperation", - EntityField: "EntityField", - EntityContext: "EntityContext", - Entity: "Entity", - Filter: "Filter", - First: "First", - Count: "Count", - InlineCount: "InlineCount", - Single: "Single", - Find: "Find", - Some: "Some", - Every: "Every", - ToArray: "ToArray", - BatchDelete: "BatchDelete", - ForEach: "ForEach", - Projection: "Projection", - EntityMember: "EntityMember", - EntityFieldOperation: "EntityFieldOperation", - FrameOperation: "FrameOperation", - EntityFunctionOperation: "EntityFunctionOperation", - ContextFunctionOperation: "ContextFunctionOperation", - EntityBinary: "EntityBinary", - Code: "Code", - ParametricQuery: "ParametricQuery", - MemberInfo: "MemberInfo", - QueryParameter: "QueryParameter", - ComplexEntityField: "ComplexEntityField", - - Take: "Take", - Skip: "Skip", - OrderBy: "OrderBy", - OrderByDescending: "OrderByDescending", - Include: "Include", - - IndexedPhysicalAnd:"IndexedDBPhysicalAndFilterExpression", - IndexedLogicalAnd:"IndexedDBLogicalAndFilterExpression", - IndexedLogicalOr: "IndexedDBLogicalOrFilterExpression", - IndexedLogicalIn: "IndexedDBLogicalInFilterExpression" -}); - -$data.BinaryOperator = function () { - /// - /// - /// -} - -$data.binaryOperators = [ - { operator: "==", expressionType: $data.Expressions.ExpressionType.Equal, type: "boolean", implementation: function (a, b) { return a == b; } }, - { operator: "===", expressionType: $data.Expressions.ExpressionType.EqualTyped, type: "boolean", implementation: function (a, b) { return a === b; } }, - { operator: "!=", expressionType: $data.Expressions.ExpressionType.NotEqual, type: "boolean", implementation: function (a, b) { return a != b; } }, - { operator: "!==", expressionType: $data.Expressions.ExpressionType.NotEqualTyped, type: "boolean", implementation: function (a, b) { return a !== b; } }, - { operator: ">", expressionType: $data.Expressions.ExpressionType.GreaterThen, type: "boolean", implementation: function (a, b) { return a > b; } }, - { operator: ">=", expressionType: $data.Expressions.ExpressionType.GreaterThenOrEqual, type: "boolean", implementation: function (a, b) { return a >= b; } }, - { operator: "<=", expressionType: $data.Expressions.ExpressionType.LessThenOrEqual, type: "boolean", implementation: function (a, b) { return a <= b; } }, - { operator: "<", expressionType: $data.Expressions.ExpressionType.LessThen, type: "boolean", implementation: function (a, b) { return a < b; } }, - { operator: "&&", expressionType: $data.Expressions.ExpressionType.And, type: "boolean", implementation: function (a, b) { return a && b; } }, - { operator: "||", expressionType: $data.Expressions.ExpressionType.Or, type: "boolean", implementation: function (a, b) { return a || b; } }, - { operator: "&", expressionType: $data.Expressions.ExpressionType.AndBitwise, type: "number", implementation: function (a, b) { return a & b; } }, - { operator: "|", expressionType: $data.Expressions.ExpressionType.OrBitwise, type: "number", implementation: function (a, b) { return a | b; } }, - { operator: "+", expressionType: $data.Expressions.ExpressionType.Add, type: "number", implementation: function (a, b) { return a + b; } }, - { operator: "-", expressionType: $data.Expressions.ExpressionType.Subtract, type: "number", implementation: function (a, b) { return a - b; } }, - { operator: "/", expressionType: $data.Expressions.ExpressionType.Divide, type: "number", implementation: function (a, b) { return a / b; } }, - { operator: "%", expressionType: $data.Expressions.ExpressionType.Modulo, type: "number", implementation: function (a, b) { return a % b; } }, - { operator: "*", expressionType: $data.Expressions.ExpressionType.Multiply, type: "number", implementation: function (a, b) { return a * b; } }, - { operator: "[", expressionType: $data.Expressions.ExpressionType.ArrayIndex, type: "number", implementation: function (a, b) { return a[b]; } }, - { operator: "in", expressionType: $data.Expressions.ExpressionType.In, type: 'boolean', implementation: function (a, b) { return a in b; } } -]; - - -$data.binaryOperators.resolve = function (operator) { - var result = $data.binaryOperators.filter(function (item) { return item.operator == operator; }); - if (result.length > 0) - return operator; - //Guard.raise("Unknown operator: " + operator); -}; - -$data.binaryOperators.contains = function (operator) { - return $data.binaryOperators.some(function (item) { return item.operator == operator; }); -}; - -$data.binaryOperators.getOperator = function (operator) { - /// - var result = $data.binaryOperators.filter(function (item) { return item.operator == operator; }); - if (result.length < 1) - Guard.raise("Unknown operator: " + operator); - return result[0]; -}; - - -$data.unaryOperators = [ - { operator: "+", arity: "prefix", expressionType: $data.Expressions.ExpressionType.Positive, type: "number", implementation: function (operand) { return +operand; } }, - { operator: "-", arity: "prefix", expressionType: $data.Expressions.ExpressionType.Negative, type: "number", implementation: function (operand) { return -operand; } }, - { operator: "++", arity: "prefix", expressionType: $data.Expressions.ExpressionType.Increment, type: "number", implementation: function (operand) { return ++operand; } }, - { operator: "--", arity: "prefix", expressionType: $data.Expressions.ExpressionType.Decrement, type: "number", implementation: function (operand) { return --operand; } }, - { operator: "++", arity: "suffix", expressionType: $data.Expressions.ExpressionType.Increment, type: "number", implementation: function (operand) { return operand++; } }, - { operator: "!", arity: "prefix", expressionType: $data.Expressions.ExpressionType.Not, type: "boolean", implementation: function (operand) { return !operand; } }, - { operator: "--", arity: "suffix", expressionType: $data.Expressions.ExpressionType.Decrement, type: "number", implementation: function (operand) { return operand--; } } - - //{ operator: "new", expressionType : $data.Expressions.ExpressionType.New, type: "object", implementation: function(operand) { return new operand; } -]; - -$data.unaryOperators.resolve = function (operator) { - var result = $data.unaryOperators.filter(function (item) { return item.operator == operator; }); - if (result.length > 0) - return operator; - //Guard.raise("Unknown operator: " + operator); -}; - -$data.unaryOperators.contains = function (operator) { - return $data.unaryOperators.some(function (item) { return item.operator == operator; }); -}; - -$data.unaryOperators.getOperator = function (operator, arity) { - /// - var result = $data.unaryOperators.filter(function (item) { return item.operator == operator && (!arity || item.arity == arity); }); - if (result.length < 1) - Guard.raise("Unknown operator: " + operator); - return result[0]; -}; - - -$data.timeIt = function (fn, iterations) { - iterations = iterations || 1; - - console.time("!"); - for (var i = 0; i < iterations; i++) { - fn(); - } - console.timeEnd("!"); -} - -$data.Expressions.OperatorTypes = { - UNARY: "UNARY", // { type:UNARY, executable:true, operator:, operand: } - INCDEC: "INCDEC", // { type:INCDEC, executable:true, operator:, operand:, suffix: } - DECISION: "DECISION", // { type:DECISION, executable:true, expression:, left:, right: } - METHODCALL: "METHODCALL", // { type:METHODCALL, executable:true, object:, method:, args: } - NEW: "NEW", // { type:NEW, executable:true, values: [] }; - JSONASSIGN: "JSONASSIGN", // { type:JSONASSIGN, executable:true, left:, right: } - ARRAYACCESS: "ARRAYACCESS", // { type:ARRAYACCESS, executable:true, array:, index: } - UNKNOWN: "UNKNOWN" -}; - -$data.executable = true; - -function jsonify(obj) { return JSON.stringify(obj, null, "\t"); } - -$C('$data.Expressions.ExpressionNode', null, null, { - constructor: function () { - ///Provides a base class for all Expressions. - ///Represents the expression type of the node - ///For the list of expression node types refer to $data.Expressions.ExpressionType - /// - ///The result type of the expression - ///True if the expression can be evaluated to yield a result - ///this.nodeType = $data.Expressions.ExpressionType.Unknown; - ///this.type = type; - ///this.nodeType = $data.Expressions.ExpressionType.Unknown; - ///this.executable = (executable === undefined || executable === null) ? true : executable; - ///TODO - this.expressionType = this.constructor; - }, - - getJSON: function () { return jsonify(this); }, - - //TOBLOG maybe - /*expressionType: { - value: undefined, - ////OPTIMIZE - set: function (value) { - var _expressionType; - Object.defineProperty(this, "expressionType", { - set: function (value) { - if (typeof value === 'string') { - value = Container.resolveType(value); - } - _expressionType = value; - }, - get: function (value) { - //IE ommits listing JSON.stringify in call chain - - if (arguments.callee.caller == jsonify || arguments.callee.caller == JSON.stringify) { - return Container.resolveName(_expressionType); - } - return _expressionType; - }, - enumerable: true - }); - - this.expressionType = value; - }, - get: function () { return undefined; }, - enumerable: true - },*/ - expressionType: { - set: function (value) { - if (typeof value === 'string') { - value = Container.resolveType(value); - } - this._expressionType = value; - }, - get: function (value) { - //IE ommits listing JSON.stringify in call chain - - if (arguments.callee.caller == jsonify || arguments.callee.caller == JSON.stringify) { - return Container.resolveName(this._expressionType); - } - return this._expressionType; - }, - enumerable: true - }, - ///toString: function () { }, - nodeType: { value: $data.Expressions.ExpressionType.Unknown, writable: false }, - - type: {}, - - isTerminated: { value: false }, - - toString: function () { - return this.value; - } -}, null); - - -$C('$data.Expressions.UnaryExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (operand, operator, nodeType, resolution) { - /// - /// Represents an operation with only one operand and an operator - /// - /// - /// - /// - /// - this.operand = operand; - this.operator = operator; - this.nodeType = nodeType; - this.resolution = resolution; - }, - - operator: { value: undefined, writable: true }, - operand: { value: undefined, writable: true }, - nodeType: { value: undefined, writable: true } -}); -$C('$data.Expressions.ArrayLiteralExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (items) { - /// - /// - /// - this.items = items || []; - }, - nodeType: { value: $data.Expressions.ExpressionType.ArrayLiteral, writable: true }, - - items: { value: undefined, dataType: Array, elementType: $data.Expressions.ExpressionNode }, - - toString: function (debug) { - //var result; - //result = debug ? this.type + " " : ""; - //result = result + this.name; - ///Represents a call to an object or global method - ///The expression for object that has the method - ///The member descriptor - this.expression = expression; - this.member = member; - this.args = args; - }, - - nodeType: { - value: $data.Expressions.ExpressionType.Call - }, - - expression: { - value: undefined, - dataType: $data.Expressions.ExpressionNode, - writable: true - }, - - member: { - value: undefined, - dataType: $data.MemberDefinition, - writable: true - }, - - type: { - value: undefined, - writable: true - }, - - implementation: { - get: function () { - return function(thisObj, method, args) { - if (typeof method !== 'function') { - method = thisObj[method]; - } - Guard.requireType("method", method, Function); - return method.apply(thisObj, args); - }; - }, - set: function (value) { Guard.raise("Property can not be set"); } - }, - - toString: function (debug) { - return this.object.toString() + "." + this.member.toString() + "(" + ")"; - } - -}); -$C('$data.Expressions.CodeParser', null, null, { - - constructor: function (scopeContext) { - /// - /// - /// - /// - /// - this.scopeContext = scopeContext; - this.lambdaParams = []; - }, - - log: function(logInfo) { - if (this.scopeContext) - this.scopeContext.log(logInfo); - }, - - parseExpression: function (code, resolver) { - /// - ///Parses the provided code and returns a parser result with parser information - ///The JavaScript code to parse ex: "function (a,b,c) { return a + b /c }" - ///The ParameterResolver class that resolves vaiable and parameteres references - /// - /// - if (typeof code === 'object') { code = ''; } - var result = { - success: true, - errorMessage: '', - errorDetails: '' - }; - /// - - //console.log(code.toString()); - if ($data.Acorn){ - //console.log('using acorn.js'); - return { success: true, expression: this.ParserBuild($data.Acorn.parse('(' + code.toString() + ')').body[0]), errors: [] }; - }else if ($data.Esprima){ - //console.log('using esprima.js'); - return { success: true, expression: this.ParserBuild($data.Esprima.parse('(' + code.toString() + ')').body[0]), errors: [] }; - }else{ - //console.log('using JayLint'); - var AST = $data.ASTParser.parseCode(code); - this.log({ event: "AST", data: AST }); - if (!AST.success) { - return { - success: false, - error: "ASTParser error", - errorMessage: (AST.errors) ? JSON.stringify(AST.errors) : "could not get code" - }; - } - var b = this.Build2(AST.tree.first[0]); - result = { success: true, expression: b, errors: AST.errors }; - return result; - } - }, - - createExpression: function (code, resolver) { - /// - ///Parses the provided code and returns a JavaScript code expression tree - ///The JavaScript code to parse ex: "a + b /c" - ///The ParameterResolver class that resolves vaiable and parameteres references - /// - /// - /// - ///Parses the provided code and returns a JavaScript code expression tree - ///The JavaScript function to parse ex: "function (a,b,c) { return a + b /c }" - ///The ParameterResolver class that resolves vaiable and parameteres references - /// - /// - - var result = this.parseExpression(code, resolver); - if (!result.success) { - Guard.raise("ExpressionParserError: " + result.errorMessage); - } - return result.expression; - }, - - ParserBuild: function(node){ - //console.log(node); - return this['Parser' + node.type](node); - }, - - ParserExpressionStatement: function(node){ - return this.ParserBuild(node.expression); - }, - - ParserBlockStatement: function(node){ - return this.ParserBuild(node.body[0]); - }, - - ParserReturnStatement: function(node){ - return this.ParserBuild(node.argument); - }, - - ParserMemberExpression: function(node){ - return new $data.Expressions.PropertyExpression( - this.ParserBuild(node.object), - new $data.Expressions.ConstantExpression(node.property.name || node.property.value, typeof (node.property.name || node.property.value)) - ); - }, - - ParserIdentifier: function(node){ - return this.ParserParameter(node, - this.lambdaParams.indexOf(node.name) > -1 - ? $data.Expressions.ExpressionType.LambdaParameterReference - : $data.Expressions.ExpressionType.Parameter - ); - }, - - ParserObjectExpression: function(node){ - var props = new Array(node.properties.length); - for (var i = 0; i < node.properties.length; i++){ - props[i] = this.ParserProperty(node.properties[i]); - } - - return new $data.Expressions.ObjectLiteralExpression(props); - }, - - ParserArrayExpression: function(node){ - var items = new Array(node.elements.length); - for (var i = 0; i < node.elements.length; i++){ - items[i] = this.ParserBuild(node.elements[i]); - } - - return new $data.Expressions.ArrayLiteralExpression(items); - }, - - ParserProperty: function(node){ - return new $data.Expressions.ObjectFieldExpression(node.key.name, this.ParserBuild(node.value)); - }, - - ParserFunctionExpression: function(node){ - var params = new Array(node.params.length); - for (var i = 0; i < node.params.length; i++){ - this.lambdaParams.push(node.params[i].name); - params[i] = this.ParserParameter(node.params[i], $data.Expressions.ExpressionType.LambdaParameter); - params[i].owningFunction = result; - } - var result = new $data.Expressions.FunctionExpression(node.id ? node.id.name : node.id, params, this.ParserBuild(node.body)); - - return result; - }, - - ParserParameter: function(node, nodeType){ - var result = new $data.Expressions.ParameterExpression(node.name, null, nodeType); - if (nodeType == $data.Expressions.ExpressionType.LambdaParameterReference){ - result.paramIndex = this.lambdaParams.indexOf(node.name); - } - - return result; - }, - - ParserLogicalExpression: function(node){ - return this.ParserBinaryExpression(node); - }, - - ParserOperators: { - value: { - "==": { expressionType: $data.Expressions.ExpressionType.Equal, type: "boolean", implementation: function (a, b) { return a == b; } }, - "===": { expressionType: $data.Expressions.ExpressionType.EqualTyped, type: "boolean", implementation: function (a, b) { return a === b; } }, - "!=": { expressionType: $data.Expressions.ExpressionType.NotEqual, type: "boolean", implementation: function (a, b) { return a != b; } }, - "!==": { expressionType: $data.Expressions.ExpressionType.NotEqualTyped, type: "boolean", implementation: function (a, b) { return a !== b; } }, - ">": { expressionType: $data.Expressions.ExpressionType.GreaterThen, type: "boolean", implementation: function (a, b) { return a > b; } }, - ">=": { expressionType: $data.Expressions.ExpressionType.GreaterThenOrEqual, type: "boolean", implementation: function (a, b) { return a >= b; } }, - "<=": { expressionType: $data.Expressions.ExpressionType.LessThenOrEqual, type: "boolean", implementation: function (a, b) { return a <= b; } }, - "<": { expressionType: $data.Expressions.ExpressionType.LessThen, type: "boolean", implementation: function (a, b) { return a < b; } }, - "&&": { expressionType: $data.Expressions.ExpressionType.And, type: "boolean", implementation: function (a, b) { return a && b; } }, - "||": { expressionType: $data.Expressions.ExpressionType.Or, type: "boolean", implementation: function (a, b) { return a || b; } }, - "&": { expressionType: $data.Expressions.ExpressionType.AndBitwise, type: "number", implementation: function (a, b) { return a & b; } }, - "|": { expressionType: $data.Expressions.ExpressionType.OrBitwise, type: "number", implementation: function (a, b) { return a | b; } }, - "+": { expressionType: $data.Expressions.ExpressionType.Add, type: "number", implementation: function (a, b) { return a + b; } }, - "-": { expressionType: $data.Expressions.ExpressionType.Subtract, type: "number", implementation: function (a, b) { return a - b; } }, - "/": { expressionType: $data.Expressions.ExpressionType.Divide, type: "number", implementation: function (a, b) { return a / b; } }, - "%": { expressionType: $data.Expressions.ExpressionType.Modulo, type: "number", implementation: function (a, b) { return a % b; } }, - "*": { expressionType: $data.Expressions.ExpressionType.Multiply, type: "number", implementation: function (a, b) { return a * b; } }, - "[": { expressionType: $data.Expressions.ExpressionType.ArrayIndex, type: "number", implementation: function (a, b) { return a[b]; } }, - "in": { expressionType: $data.Expressions.ExpressionType.In, type: 'boolean', implementation: function (a, b) { return a in b; } } - } - }, - - ParserUnaryOperators: { - value: { - "+": { arity: "prefix", expressionType: $data.Expressions.ExpressionType.Positive, type: "number", implementation: function (operand) { return +operand; } }, - "-": { arity: "prefix", expressionType: $data.Expressions.ExpressionType.Negative, type: "number", implementation: function (operand) { return -operand; } }, - "++true": { arity: "prefix", expressionType: $data.Expressions.ExpressionType.Increment, type: "number", implementation: function (operand) { return ++operand; } }, - "--true": { arity: "prefix", expressionType: $data.Expressions.ExpressionType.Decrement, type: "number", implementation: function (operand) { return --operand; } }, - "++false": { arity: "suffix", expressionType: $data.Expressions.ExpressionType.Increment, type: "number", implementation: function (operand) { return operand++; } }, - "!": { arity: "prefix", expressionType: $data.Expressions.ExpressionType.Not, type: "boolean", implementation: function (operand) { return !operand; } }, - "--false": { arity: "suffix", expressionType: $data.Expressions.ExpressionType.Decrement, type: "number", implementation: function (operand) { return operand--; } } - } - }, - - ParserUnaryExpression: function(node){ - return new $data.Expressions.UnaryExpression(this.ParserBuild(node.argument), this.ParserUnaryOperators[node.operator], this.ParserUnaryOperators[node.operator].expressionType); - }, - - ParserUpdateExpression: function(node){ - return new $data.Expressions.UnaryExpression(this.ParserBuild(node.argument), this.ParserUnaryOperators[node.operator + node.prefix], this.ParserUnaryOperators[node.operator + node.prefix].nodeType); - }, - - ParserBinaryExpression: function(node){ - return new $data.Expressions.SimpleBinaryExpression( - this.ParserBuild(node.left), - this.ParserBuild(node.right), - this.ParserOperators[node.operator].expressionType, - node.operator, - this.ParserOperators[node.operator].type - ); - }, - - ParserThisExpression: function(node){ - return new $data.Expressions.ThisExpression(); - }, - - ParserLiteral: function(node){ - return new $data.Expressions.ConstantExpression(node.value, typeof node.value); - }, - - ParserCallExpression: function(node){ - var method = this.ParserBuild(node.callee); - var args = new Array(node.arguments.length); - for (var i = 0; i < node.arguments.length; i++){ - args[i] = this.ParserBuild(node.arguments[i]); - } - - var member; - var expression; - switch (true){ - case method instanceof $data.Expressions.PropertyExpression: - expression = method.expression; - member = method.member; - break; - case method instanceof $data.Expressions.ParameterExpression: - expression = new $data.Expressions.ConstantExpression(null, typeof null); - member = method; - break; - } - - return new $data.Expressions.CallExpression(expression, member, args); - }/*, - - Build2: function (node) { - /// - /// - var n; - switch (node.arity) { - case "number": - case "string": - n = this.BuildConstant(node); - break; - case "prefix": - switch (node.value) { - case "{": - n = this.BuildObjectLiteral(node); - break; - case "[": - n = this.BuildArrayLiteral(node); - break; - case $data.unaryOperators.resolve(node.value): - n = this.BuildUnary(node); - break; - //TODO: default case - } - break; - case "suffix": - switch (node.value) { - case $data.unaryOperators.resolve(node.value): - n = this.BuildUnary(node); - break; - default: - Guard.raise("Unknown suffix: " + node.value); - } - break; - case "infix": - switch (node.value) { - case "[": - n = this.BuildArray(node); - break; - case $data.binaryOperators.resolve(node.value): - n = this.BuildSimpleBinary(node); - break; - case "function": - Guard.raise("Unexpected function arity"); - case "(": - n = this.BuildCall(node); - break; - case ".": - n = this.BuildProperty(node); - break; - default: - debugger; - //TODO: remove debugger, throw exception or break - } - break; - case "statement": - switch (node.value) { - case "function": - n = this.BuildFunction(node); - //TODO: consider adding break - } - break; - default: - switch (node.value) { - case "function": - n = this.BuildFunction(node); - break; - case "true": - case "false": - case "null": - n = this.BuildConstant(node); - break; - case "this": - n = this.BuildThis(node); - break; - default: - n = this.BuildParameter(node); - break; - } - } - return n; - }, - - BuildThis: function (node) { - var result = Container.createThisExpression(); - return result; - }, - - BuildConstant: function (node) { - /// - var value = node.value; - var type = node.type; - if (node.reserved === true) { - switch (node.value) { - case "true": value = true; type = typeof true; break; - case "false": value = false; type = typeof false; break; - case "null": value = null; type = typeof null; break; - //TODO: missing default case - } - } - var result = new $data.Expressions.ConstantExpression(value, type); - return result; - }, - - BuildFunctionParameter: function (node) { - - }, - - BuildArray: function (node) { - switch (node.second.type) { - case "string": - return this.BuildProperty(node); - case "number": - default: - return this.BuildSimpleBinary(node); - } - }, - - BuildParameter: function (node) { - /// - /// - var paramName = node.value; - //TODO - //var paramType = this.resolver.resolveParameterType(node); - var nodeType = node.funct ? $data.Expressions.ExpressionType.LambdaParameter : - this.lambdaParams.indexOf(node.value) > -1 ? - $data.Expressions.ExpressionType.LambdaParameterReference : $data.Expressions.ExpressionType.Parameter; - var result = new $data.Expressions.ParameterExpression(node.value, null, nodeType); - - if (nodeType == $data.Expressions.ExpressionType.LambdaParameterReference) { - result.paramIndex = this.lambdaParams.indexOf(node.value); - } - - return result; - }, - - BuildArrayLiteral: function(node) { - var self = this; - var items = node.first.map(function (item) { return self.Build2(item); }); - var result = new $data.Expressions.ArrayLiteralExpression(items); - return result; - }, - - BuildObjectLiteral: function (node) { - var self = this; - var fields = node.first.map(function (item) { - var eItem = self.Build2(item.first); - var result = new $data.Expressions.ObjectFieldExpression(item.value, eItem); - return result; - }); - var result = new $data.Expressions.ObjectLiteralExpression(fields); - return result; - }, - - BuildFunction: function (node) { - /// - /// - var self = this; - var paramStack = []; - var params = node.first && node.first.map(function (paramNode) { - //paramStack.push(paramNode.value); - this.lambdaParams.push(paramNode.value); - return self.BuildParameter(paramNode); - }, this); - params = params || []; - - //skipping return for convenience - //Possible we should raise an error as predicates and selectors can - //not be code blocks just expressions - - var hasReturn = node.block.length == 0 ? false : - node.block[0].value === "return" ? true : false; - var body = (node.block.length > 0) ? this.Build2(hasReturn ? node.block[0].first : node.block[0]) : null; - - paramStack.forEach(function () { this.lambdaParams.pop(); }, this); - - var result = new $data.Expressions.FunctionExpression(node.value, params, body); - params.forEach(function (param) { - param.owningFunction = result; - }); - - //TODO place on prototyope - result.name = node.name; - return result; - }, - - BuildCall: function (node) { - var self = this; - var method = self.Build2(node.first); - var args = node.second.map(function (exp) { return self.Build2(exp); }); - var member; - var expression; - switch(true){ - case method instanceof $data.Expressions.PropertyExpression: - expression = method.expression; - member = method.member; - break; - case method instanceof $data.Expressions.ParameterExpression: - expression = Container.createConstantExpression(null, typeof null); - member = method; - break; - //TODO: missing default case - } - - var result = Container.createCallExpression(expression, member, args); - return result; - }, - - BuildProperty: function (node) { - ///Builds a PropertyExpression from the AST node - /// - /// - var expression = this.Build2(node.first); - //TODO - //var type = expression.type; - //var member = type.getMemberDefinition() - //TODO how to not if????? - var member; - if (node.second.identifier) { - member = new $data.Expressions.ConstantExpression(node.second.value, "string"); - } else { - member = this.Build2(node.second); - } - var result = new $data.Expressions.PropertyExpression(expression, member); - return result; - }, - - - BuildUnary: function(node) { - var operator = $data.unaryOperators.getOperator(node.value, node.arity); - var nodeType = operator.expressionType; - var operand = this.Build2(node.first); - var result = new $data.Expressions.UnaryExpression(operand, operator, nodeType); - return result; - }, - - BuildSimpleBinary: function (node) { - /// - - var operator = $data.binaryOperators.getOperator(node.value); - var nodeType = operator.expressionType; - - var left = this.Build2(node.first || node.left); - var right = this.Build2(node.second || node.right); - var result = new $data.Expressions.SimpleBinaryExpression(left, right, nodeType, node.value, operator.type); - return result; - } - - //Build: function (node, expNode) { - // var n; - // switch (node.arity) { - // case "ternary": - // if (node.value == "?") - // n = this.BuildDecision(node, expNode); - // else - // Guard.raise("Value of ternary node isn't implemented: " + node.value); - // break; - // case null: - // default: - // Guard.raise("Arity isn't implemented: " + node.arity); - // } - // return n; - //},*/ - -}); - -$C('$data.Expressions.ConstantExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (value, type, name) { - this.value = value; - //TODO - //this.type = Container.getTypeName(value); - - this.type = type; - this.name = name; - if (!Object.isNullOrUndefined(this.value)) { - this.type = Container.resolveType(this.type) - if (Container.resolveType(Container.getTypeName(this.value)) !== this.type) - this.value = Container.convertTo(value, this.type); - } - }, - nodeType: { value: $data.Expressions.ExpressionType.Constant, enumerable: true }, - type: { value: Object, writable: true }, - value: { value: undefined, writable: true }, - toString: function (debug) { - //return "[constant: " + this.value.toString() + "]"; - return this.value.toString(); - } -}); - - -$C('$data.Expressions.FunctionExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (name, parameters, body) { - /// - ///Represents a function declaration. - ///Function name - ///The list of function parameters - /// - /// - ///The list of function parameters - ///The function body - - this.parameters = parameters || []; - this.name = name; - this.body = body; - }, - - toString: function (debug) { - var paramStrings = this.parameters.map(function (p) { - return p.toString(); - }); - paramStrings = paramStrings.join(","); - var bodyString = (this.body ? this.body.toString(debug) : ''); - return "function " + this.name + "(" + paramStrings + ") { " + bodyString + "}"; - }, - nodeType: { value: $data.Expressions.ExpressionType.Function, writable: true }, - parameters: { value: undefined, dataType: Array, elementType: $data.Expressions.ParameterExpression }, - body: { value: undefined, dataType: $data.Expressions.ExpressionNode }, - type: {} -}, null); -$C('$data.Expressions.ObjectFieldExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (fieldName, expression) { - /// - /// - this.fieldName = fieldName; - this.expression = expression; - }, - nodeType: { value: $data.Expressions.ExpressionType.ObjectField, writable: true }, - - toString: function (debug) { - //var result; - //result = debug ? this.type + " " : ""; - //result = result + this.name; - var result = "unimplemented"; - return result; - } -}, null); - -$C('$data.Expressions.ObjectLiteralExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (members) { - ///Represent an object initializer literal expression Ex: { prop: value} - /// - this.members = members; - }, - nodeType: { value: $data.Expressions.ExpressionType.ObjectLiteral, writable: true }, - - toString: function (debug) { - //var result; - //result = debug ? this.type + " " : ""; - //result = result + this.name; - var result = "unimplemented"; - return result; - }, - - implementation: { - get: function () { - return function(namesAndValues) { - var result = { }; - namesAndValues.forEach(function(item) { - result[item.name] = item.value; - }); - return result; - }; - }, - set: function () { - } - } - -}, null); -$C('$data.Expressions.PagingExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (source, expression, nType) { - /// - /// - this.source = source; - this.amount = expression; - this.nodeType = nType; - }, - nodeType: { value: $data.Expressions.ExpressionType.Unknown, writable: true }, - - toString: function (debug) { - //var result; - //result = debug ? this.type + " " : ""; - //result = result + this.name; - var result = "unimplemented"; - return result; - } -}, null); -$C('$data.Expressions.ParameterExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (name, type, nodeType) { - /// - /// - //this.writePropertyValue("name", name); - //this.writePropertyValue("type", type); - this.nodeType = nodeType || $data.Expressions.ExpressionType.Parameter; - this.name = name; - this.type = type || "unknown"; - var _owningFunction; - }, - - owningFunction: { value: undefined, enumerable: false }, - nodeType: { value: $data.Expressions.ExpressionType.Parameter, writable: true }, - name: { value: undefined, dataType: String, writable: true }, - type: { value: undefined, dataType: "object", writable: true}, - toString: function (debug) { - var result; - result = debug ? this.type + " " : ""; - result = result + this.name; - return result; - } -}, null); -$C('$data.Expressions.PropertyExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (expression, member) { - ///Represents accessing a property or field of an object - ///The expression for the property owner object - ///The member descriptor - ///The expression for the property owner object - ///The member descriptor - - this.expression = expression; - this.member = member; - - this.type = member.dataType; - }, - - nodeType: { - value: $data.Expressions.ExpressionType.MemberAccess - }, - - expression: { - value: undefined, - dataType: $data.Expressions.ExpressionNode, - writable: true - }, - - implementation: { - get: function () { - return function (holder, memberName) { - if (holder[memberName] === undefined) - Guard.raise(new Exception("Parameter '" + memberName + "' not found in context", 'Property not found!')); - return holder[memberName]; - }; - }, - set: function () { - } - }, - - member: { - value: undefined, - dataType: $data.MemberDefinition, - writable: true - }, - - type: { - value: undefined, - writable: true - }, - - toString: function (debug) { - return this.expression.toString() + "." + this.member.toString(); - } - -}); - -$C('$data.Expressions.SimpleBinaryExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (left, right, nodeType, operator, type, resolution) { - ///Represents a bin operation with left and right operands and an operator/// - ///The left element of the binary operation - ///The right element of the binary operation - /// - this.left = left; - this.right = right; - this.nodeType = nodeType; - this.operator = operator; - this.type = type; - this.resolution = resolution; - }, - - implementation: { - get: function () { - return $data.binaryOperators.getOperator(this.operator).implementation; - }, - set: function () { } - - }, - //nodeType: { value: $data.Expressions.ExpressionType }, - type: { value: "number", writable: true } -}); -$C('$data.Expressions.ThisExpression', $data.Expressions.ExpressionNode, null, { - nodeType: { value: $data.Expressions.ExpressionType.This } -}); -$C('$data.Expressions.ExpressionVisitor', null, null, - { - constructor: function () { - this._deep = 0; - }, - - Visit: function (eNode, context) { - /// - /// - /// - // - - //this._deep = this._deep + 1; - if (!eNode) { - return eNode; - } - - var result = null; - - switch (eNode.expressionType) { - case $data.Expressions.ParameterExpression: - result = this.VisitParameter(eNode, context); - break; - case $data.Expressions.ConstantExpression: - result = this.VisitConstant(eNode, context); - break; - case $data.Expressions.FunctionExpression: - result = this.VisitFunction(eNode, context); - break; - case $data.Expressions.CallExpression: - result = this.VisitCall(eNode, context); - break; - case $data.Expressions.SimpleBinaryExpression: - result = this.VisitBinary(eNode, context); - break; - case $data.Expressions.PropertyExpression: - result = this.VisitProperty(eNode, context); - break; - //result = th - case $data.Expressions.ThisExpression: - result = this.VisitThis(eNode, context); - break; - case $data.Expressions.ObjectLiteralExpression: - result = this.VisitObjectLiteral(eNode, context); - break; - case $data.Expressions.ObjectFieldExpression: - result = this.VisitObjectField(eNode, context); - break; - case $data.Expressions.ArrayLiteralExpression: - result = this.VisitArrayLiteral(eNode, context); - break; - case $data.Expressions.UnaryExpression: - result = this.VisitUnary(eNode, context); - break; - case $data.Expressions.EntityContextExpression: - result = this.VisitEntityContext(eNode, context); - break; - default: - debugger; - break; - //case VARIABLE: - - // result = this.VisitVariable(eNode, context); - // break; - //case MEMBERACCESS: - // result = this.VisitMember(eNode, context); - // break; - //case BINARY: - // result = this.VisitBinary(eNode, context); - // break; - //case UNARY: - // result = this.VisitUnary(eNode, context); - // break; - //case INCDEC: - // result = this.VisitIncDec(eNode, context); - // break; - //case EQUALITY: result = this.VisitEquality(eNode, context); break; - //case DECISION: result = this.VisitDecision(eNode, context); break; - //case METHODCALL: result = this.VisitMethodCall(eNode, context); break; - //case NEW: result = this.VisitNew(eNode, context); break; - //case JSONASSIGN: result = this.VisitJsonAssign(eNode, context); break; - //case ARRAYACCESS: result = this.VisitArrayAccess(eNode, context); break; - //default: - // Guard.raise("Type isn't implemented: " + eNode.type); - } - - this._deep = this._deep - 1; - return result; - }, - - VisitArrayLiteral: function(eNode, context) { - /// - var self = this; - var items = eNode.items.map(function (item) { - return self.Visit(item, context); - }); - var result = Container.createArrayLiteralExpression(items); - return result; - }, - - VisitObjectLiteral: function(eNode, context) { - /// - var self = this; - var members = eNode.members.map(function (member) { - return self.Visit(member, context); - }); - var result = Container.createObjectLiteralExpression(members); - return result; - }, - - VisitObjectField: function(eNode, context) { - /// - var expression = this.Visit(eNode.expression, context); - var result = Container.createObjectFieldExpression(eNode.fieldName, expression); - return result; - }, - - VisitThis: function (eNode, context) { - return eNode; - }, - VisitCall: function (eNode, context) { - /// - var self = this; - var args = eNode.args.map(function (arg) { return this.Visit(arg, context); }, this); - var expression = this.Visit(eNode.expression, context); - var member = this.Visit(eNode.member, context); - return new $data.Expressions.CallExpression(expression, member, args); - }, - - VisitParameter: function(eNode, context) { - /// - /// - //var result = new $data.Expressions.ParameterExpression(eNode.name, eNode.type, eNode.nodeType); - return eNode; - }, - - VisitConstant: function (eNode, context) { - /// - /// - //var result = new $data.Expressions.ParameterExpression(eNode.name, eNode.type, eNode.nodeType); - return eNode; - }, - - VisitFunction: function(eNode, context) { - /// - var self = this; - - var params = eNode.parameters.map(function (p, i) { - return self.Visit(p, context); - }); - - var body = self.Visit(eNode.body, context); - var result = new $data.Expressions.FunctionExpression(eNode.name, params, body); - return result; - }, - - VisitBinary: function (eNode, context) { - /// - /// - /// - // - - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - return new $data.Expressions.SimpleBinaryExpression(left, right, eNode.nodeType, eNode.operator, eNode.type); - }, - - VisitProperty: function (eNode, context) { - /// - var expression = this.Visit(eNode.expression, context); - var member = this.Visit(eNode.member, context); - return new $data.Expressions.PropertyExpression(expression, member); - //var member = - }, - - VisitUnary: function (eNode, context) { - /// - /// - /// - /// - var operand = this.Visit(eNode.operand, context); - if (operand === eNode.operand) - return eNode; - return new $data.Expressions.UnaryExpression(operand, eNode.operator, eNode.nodeType); - }, - - VisitEntityContext: function (eNode, context) { - /// - /// - //var result = new $data.Expressions.ParameterExpression(eNode.name, eNode.type, eNode.nodeType); - return eNode; - }, - - VisitDecision: function (eNode, context) { - /// - /// - /// - // - - var expression = this.Visit(eNode.expression, context); - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - if (expression === eNode.expression && left === eNode.left && right === eNode.right) - return eNode; - return $data.Expressions.ExpressionNodeTypes.DecisionExpressionNode.create(eNode.executable, expression, left, right); - }, - - VisitNew: function (eNode, context) { - /// - /// - /// - // - - var values = this.VisitArray(eNode.values, context); - if (values === eNode.values) - return eNode; - return $data.Expressions.ExpressionNodeTypes.NewExpressionNode.create(true, values); - }, - VisitArrayAccess: function (eNode, context) { - /// - /// - /// - // - - var array = this.Visit(eNode.array, context); - var index = this.Visit(eNode.index, context); - if (array === eNode.array && index === eNode.index) - return eNode; - return $data.Expressions.ExpressionNodeTypes.ArrayAccessExpressionNode.create(true, array, index); - }, - VisitArray: function (eNodes, context) { - var args = []; - var ok = true; - for (var i = 0; i < eNodes.length; i++) { - args[i] = this.Visit(eNodes[i], context); - ok = ok && args[i] === eNodes[i]; - } - return ok ? eNodes : args; - }, - GetMemberChain: function (memberAccess, context) { - // { type:MEMBERACCESS, executable:true, expression:, member: } - if (memberAccess.expression.type == MEMBERACCESS) { - var a = this.GetMemberChain(memberAccess.expression, context); - a.push(memberAccess.member); - return a; - } - return [memberAccess.expression, memberAccess.member]; - } - }, {});$C("$data.Expressions.ParameterProcessor", $data.Expressions.ExpressionVisitor, null, { - constructor: function () { - ///Provides a base class for several ParameterProcessors like GlobalParameterProcessor or LambdaParameterProcessor - }, - - Visit: function (node, context) { - if ((node instanceof $data.Expressions.ParameterExpression || - node instanceof $data.Expressions.ThisExpression) - && this.canResolve(node)) { - var result = this.resolve(node, context); - if (result !== node) - result["resolvedBy"] = this.constructor.name; - return result; - } else { - return node; - } - }, - - canResolve: function (paramExpression) { - /// - Guard.raise("Pure method"); - }, - resolve: function (paramExpression) { - /// - Guard.raise("Pure method"); - } -}); -$C("$data.Expressions.GlobalContextProcessor", $data.Expressions.ParameterProcessor, null, { - constructor: function (global) { - /// - this.global = global; - }, - - canResolve: function (paramExpression) { - /// - return paramExpression.nodeType == $data.Expressions.ExpressionType.Parameter && this.global && typeof this.global === 'object' && - paramExpression.name in this.global; - }, - - resolve: function (paramExpression) { - /// - /// - var resultValue = this.global[paramExpression.name]; - var expression = Container.createConstantExpression(resultValue, typeof resultValue, paramExpression.name); - return expression; - } - -}); - - - -$C("$data.Expressions.ConstantValueResolver", $data.Expressions.ParameterProcessor, null, { - constructor: function (paramsObject, global, scopeContext) { - /// - this.globalResolver = Container.createGlobalContextProcessor(global); - this.paramResolver = Container.createGlobalContextProcessor(paramsObject); - this.paramsObject = paramsObject; - this.scopeContext = scopeContext; - }, - - canResolve: function (paramExpression) { - /// - return (paramExpression.name === '$context') || (paramExpression.nodeType == $data.Expressions.ExpressionType.This && this.paramsObject) - ? true : (this.paramResolver.canResolve(paramExpression) || this.globalResolver.canResolve(paramExpression)); - }, - - resolve: function (paramExpression) { - /// - /// - if (paramExpression.name === '$context') { - return Container.createEntityContextExpression(this.scopeContext); - } - if (paramExpression.nodeType == $data.Expressions.ExpressionType.This) { - return Container.createConstantExpression(this.paramsObject, typeof this.paramsObject, 'this'); - } - return this.paramResolver.canResolve(paramExpression) ? this.paramResolver.resolve(paramExpression) : this.globalResolver.resolve(paramExpression); - } - -});$C("$data.Expressions.LocalContextProcessor", $data.Expressions.GlobalContextProcessor, null, { - constructor: function (evalMethod) { - /// - this.canResolve = function (paramExpression) { - /// - return paramExpression.nodeType == $data.Expressions.ExpressionType.Parameter && - (evalMethod("typeof " + paramExpression.name) !== 'undefined'); - }; - this.resolve = function(paramExpression) { - /// - /// - var resultValue = evalMethod(paramExpression.name); - var expression = Container.createConstantExpression(resultValue, typeof resultValue); - return expression; - }; - - } - }); -$C("$data.Expressions.LambdaParameterProcessor", $data.Expressions.ParameterProcessor, null, { - constructor: function (lambdaParameterTypeInfos) { - /// - /// - var paramIndices = {}; - var $idx = "name"; - - this.canResolve = function (paramExpression, context) { - if (paramExpression.nodeType == $data.Expressions.ExpressionType.LambdaParameter) { - var fnParams = paramExpression.owningFunction.parameters; - - if (fnParams.length == 1 && paramExpression.name == fnParams[0].name) { - paramIndices[paramExpression.name] = lambdaParameterTypeInfos[0]; - return true; - } - - for (var j = 0; j < fnParams.length; j++) { - if (fnParams[j].name == paramExpression.name) { - paramIndices[paramExpression.name] = lambdaParameterTypeInfos[j]; - return true; - } - } - return false; - } - return false; - }; - - this.resolve = function(paramExpression, context) { - var lambdaParamType = paramIndices[paramExpression.name]; - var result = Container.createParameterExpression(paramExpression.name, - lambdaParamType, - $data.Expressions.ExpressionType.LambdaParameter); - result.owningFunction = paramExpression.owningFunction; - return result; - }; - } - -}); -$C('$data.Expressions.ParameterResolverVisitor', $data.Expressions.ExpressionVisitor, null, { - - constructor: function (expression, resolver) { - /// - /// ParameterResolverVisitor traverses the JavaScript Code Expression tree and converts - /// outer but otherwise execution local variable references into ConstantExpressions-t. - /// for example: context.Persons.filter(function(p) { return p.Name == document.location.href }) - /// is transformed into a constant that has the current href as its value - /// - /// - /// - this.lambdaParamCache = {}; - }, - - Visit: function (expression, resolver) { - /// - /// - //TODO base call is just ugly - return $data.Expressions.ExpressionVisitor.prototype.Visit.call(this, expression, resolver); - - }, - - - VisitArrayLiteral: function(eNode, context) { - var self = this; - var items = eNode.items.map(function (item) { return self.Visit(item, context); }); - var allLocal = items.every(function (item) { - return item instanceof $data.Expressions.ConstantExpression; - }); - - if (allLocal) { - items = items.map(function (item) { return item.value }); - return Container.createConstantExpression(items, "array"); - } else { - return Container.createArrayLiteralExpression(items); - } - }, - - VisitObjectLiteral: function(eNode, context) { - var self = this; - var members = eNode.members.map(function (item) { return self.Visit(item, context); }); - var allLocal = members.every(function (member) { - return member.expression instanceof $data.Expressions.ConstantExpression; - }); - - if (allLocal) { - var params = members.map(function (member) { return { name: member.fieldName, value: member.expression.value }; }); - var value = eNode.implementation(params); - return Container.createConstantExpression(value, typeof value); - } else { - return Container.createObjectLiteralExpression(members); - } - }, - - VisitThis: function(eNode, resolver) { - return resolver.Visit(eNode, resolver); - }, - - VisitParameter: function(eNode, resolver) { - /// - /// - /// - - var node; - ///TODO let the resolver handle lambdaReferences if it wants to deal with it - switch(eNode.nodeType){ - case $data.Expressions.ExpressionType.Parameter: - case $data.Expressions.ExpressionType.LambdaParameter: - node = resolver.Visit(eNode, resolver); - if (node.nodeType == $data.Expressions.ExpressionType.LambdaParameter) { - this.lambdaParamCache[node.name] = node; - } - return node; - case $data.Expressions.ExpressionType.LambdaParameterReference: - var lambdaParam = this.lambdaParamCache[eNode.name]; - if (lambdaParam) { - node = Container.createParameterExpression(eNode.name, - lambdaParam.type, - $data.Expressions.ExpressionType.LambdaParameterReference); - node.paramIndex = eNode.paramIndex; - //node.typeName = lambdaParam.type.name || lambdaParam.type; - return node; - } - break; - default: - return eNode; - - } - - - return eNode; - }, - - VisitConstant: function (eNode, context) { - /// - /// - return eNode; - }, - - VisitFunction: function(eNode, context) { - /// - - var self = this; - var params = eNode.parameters.map(function (p, i) { - var result = self.Visit(p, context); - return result; - }); - var body = self.Visit(eNode.body, context); - var result = new $data.Expressions.FunctionExpression(eNode.name, params, body); - - return result; - }, - - VisitBinary: function (eNode, context) { - /// - /// - /// - /// - - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - var expr = $data.Expressions; - - if (left instanceof expr.ConstantExpression && right instanceof expr.ConstantExpression) - { - var result = eNode.implementation(left.value, right.value); - return Container.createConstantExpression(result, typeof result); - } - return new Container.createSimpleBinaryExpression(left, right, eNode.nodeType, eNode.operator, eNode.type); - }, - - VisitUnary: function (eNode, context) { - /// - /// - /// - /// - - var operand = this.Visit(eNode.operand, context); - //var imp = $data.unaryOperators.getOperator( - var expr = $data.Expressions; - if (operand instanceof expr.ConstantExpression) - { - var result = eNode.operator.implementation(operand.value); - return Container.createConstantExpression(result, typeof result); - } - return new Container.createUnaryExpression(operand, eNode.operator, eNode.nodeType); - }, - - VisitProperty: function (eNode, context) { - /// - var expression = this.Visit(eNode.expression, context); - var member = this.Visit(eNode.member, context); - var result; - if (expression instanceof $data.Expressions.ConstantExpression && - member instanceof $data.Expressions.ConstantExpression) { - ///TODO implement checking for the member, throw on error - result = eNode.implementation(expression.value, member.value); - - //Method call processed before - //if (typeof result === 'function') { - // return new $data.Expressions.ConstantExpression( - // function () { return result.apply(expression.value, arguments); }); - //} - return Container.createConstantExpression(result, typeof result, expression.name + '$' + member.value); - } - if (expression === eNode.expression && member === eNode.member) - return eNode; - - result = Container.createPropertyExpression(expression, member); - return result; - }, - - VisitCall: function (eNode, context) { - /// - function isExecutable(args, body, obj) { - return body instanceof $data.Expressions.ConstantExpression && - //global methods will not have a this. - (!obj || obj instanceof $data.Expressions.ConstantExpression) && - args.every(function(item) { - return item instanceof $data.Expressions.ConstantExpression; - }); - } - var call = $data.Expressions.ExpressionVisitor.prototype.VisitCall.apply(this, arguments); - var obj = call.expression; - var body = call.member; - var args = call.args; - - function convertToValue(arg) { - if (arg instanceof $data.Expressions.ConstantExpression) - return arg.value; - return arg; - }; - - if (isExecutable(args, body, obj)) { - var fn = body.value; - if (typeof fn === 'string' && obj.value) { - fn = obj.value[fn]; - } - if (typeof fn !== 'function') { - //TODO dig that name out from somewhere - Guard.raise("Constant expression is not a method..."); - } - var value = eNode.implementation(obj.value, fn, args.map(convertToValue)); - return new $data.Expressions.ConstantExpression(value, typeof value); - } - return call; - } -}, {}); -$C("$data.Expressions.AggregatedVisitor", $data.Expressions.ExpressionVisitor, null, { - constructor: function (visitors) { - /// - - this.Visit = function (node, context) { - for (var i = 0; i < visitors.length; i++) { - var n = visitors[i].Visit(node, context); - if (n !== node) - return n; - } - return node; - }; - } - -}); -//"use strict"; // suspicious code - -$C('$data.Expressions.LogicalSchemaBinderVisitor', - $data.Expressions.ExpressionVisitor, null, - { - constructor: function (expression, binder) { - - }, - - VisitProperty: function (expression, context) { - /// - var exp = this.Visit(expression.expression, context); - var mem = this.Visit(expression.member, context); - - var type = exp.type; - var memberType = context.memberResolver.resolve(type, mem.value); - mem.type = memberType; - return Container.createPropertyExpression(exp, mem); - } - - }, {});$data.Class.define('$data.Expressions.ExpTreeVisitor', - null, null, - { - constructor: function () { - this._deep = 0; - }, - Visit: function (eNode, context) { - /// - /// - /// - // - this._deep = this._deep + 1; - var result = null; - switch (eNode.type) { - case LITERAL: result = this.VisitLiteral(eNode, context); break; - case VARIABLE: result = this.VisitVariable(eNode, context); break; - case MEMBERACCESS: result = this.VisitMember(eNode, context); break; - case BINARY: result = this.VisitBinary(eNode, context); break; - case UNARY: result = this.VisitUnary(eNode, context); break; - case INCDEC: result = this.VisitIncDec(eNode, context); break; - case EQUALITY: result = this.VisitEquality(eNode, context); break; - case DECISION: result = this.VisitDecision(eNode, context); break; - case METHODCALL: result = this.VisitMethodCall(eNode, context); break; - case NEW: result = this.VisitNew(eNode, context); break; - case JSONASSIGN: result = this.VisitJsonAssign(eNode, context); break; - case ARRAYACCESS: result = this.VisitArrayAccess(eNode, context); break; - default: - Guard.raise("Type isn't implemented: " + eNode.type); - } - this._deep = this._deep - 1; - return result; - }, - VisitLiteral: function (eNode, context) { - /// - /// - /// - // - - return eNode; - }, - VisitVariable: function (eNode, context) { - /// - /// - /// - // - - return eNode; - }, - VisitMember: function (eNode, context) { - /// - /// - /// - // - - var expression = this.Visit(eNode.expression, context); - var member = this.Visit(eNode.member, context); - if (expression === eNode.expression && member === eNode.member) - return eNode; - return $data.Expressions.ExpressionNodeTypes.MemberAccessExpressionNode.create(eNode.executable, expression, member); - }, - VisitBinary: function (eNode, context) { - /// - /// - /// - // - - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - if (left === eNode.left && right === eNode.right) - return eNode; - return $data.Expressions.ExpressionNodeTypes.BinaryExpressionNode.create(eNode.executable, eNode.operator, left, right); - }, - VisitUnary: function (eNode, context) { - /// - /// - /// - // - - var operand = this.Visit(eNode.operand, context); - if (operand === eNode.operand) - return eNode; - return $data.Expressions.ExpressionNodeTypes.UnaryExpressionNode.create(eNode.executable, eNode.operator, operand); - }, - VisitIncDec: function (eNode, context) { - /// - /// - /// - // - - var operand = this.Visit(eNode.operand, context); - if (operand === eNode.operand) - return eNode; - return $data.Expressions.ExpressionNodeTypes.IncDecExpressionNode.create(eNode.executable, eNode.operator, operand, eNode.suffix); - }, - VisitEquality: function (eNode, context) { - /// - /// - /// - // - - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - if (left === eNode.left && right === eNode.right) - return eNode; - return $data.Expressions.ExpressionNodeTypes.EqualityExpressionNode.create(eNode.executable, eNode.operator, left, right); - }, - VisitDecision: function (eNode, context) { - /// - /// - /// - // - - var expression = this.Visit(eNode.expression, context); - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - if (expression === eNode.expression && left === eNode.left && right === eNode.right) - return eNode; - return $data.Expressions.ExpressionNodeTypes.DecisionExpressionNode.create(eNode.executable, expression, left, right); - }, - VisitMethodCall: function (eNode, context) { - /// - /// - /// - // - - var object = eNode.object ? this.Visit(eNode.object, context) : null; - var args = this.VisitArray(eNode.args, context); - if (object === eNode.object && args === eNode.args) - return eNode; - return $data.Expressions.ExpressionNodeTypes.MethodcallExpressionNode.create(eNode.executable, object, eNode.method, args); - }, - VisitNew: function (eNode, context) { - /// - /// - /// - // - - var values = this.VisitArray(eNode.values, context); - if (values === eNode.values) - return eNode; - return $data.Expressions.ExpressionNodeTypes.NewExpressionNode.create(true, values); - }, - VisitJsonAssign: function (eNode, context) { - /// - /// - /// - // - - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - if (left === eNode.left && right === eNode.right) - return eNode; - left.JSONASSIGN = true; - right.JSONASSIGN = true; - return $data.Expressions.ExpressionNodeTypes.JsonAssignExpressionNode.create(true, left, right); - }, - VisitArrayAccess: function (eNode, context) { - /// - /// - /// - // - - var array = this.Visit(eNode.array, context); - var index = this.Visit(eNode.index, context); - if (array === eNode.array && index === eNode.index) - return eNode; - return $data.Expressions.ExpressionNodeTypes.ArrayAccessExpressionNode.create(true, array, index); - }, - VisitArray: function (eNodes, context) { - var args = []; - var ok = true; - for (var i = 0; i < eNodes.length; i++) { - args[i] = this.Visit(eNodes[i], context); - ok = ok && args[i] === eNodes[i]; - } - return ok ? eNodes : args; - }, - GetMemberChain: function (memberAccess, context) { - // { type:MEMBERACCESS, executable:true, expression:, member: } - if (memberAccess.expression.type == MEMBERACCESS) { - var a = this.GetMemberChain(memberAccess.expression, context); - a.push(memberAccess.member); - return a; - } - return [memberAccess.expression, memberAccess.member]; - } - }, {});$data.Class.define('$data.Expressions.SetExecutableVisitor', $data.Expressions.ExpTreeVisitor, null, -{ - Visit: function (eNode, context) { - switch (eNode.type) { - case LITERAL: return this.VisitLiteral(eNode, context); - case VARIABLE: return this.VisitVariable(eNode, context); - case MEMBERACCESS: return this.VisitMember(eNode, context); - case BINARY: return this.VisitBinary(eNode, context); - case UNARY: return this.VisitUnary(eNode, context); - case INCDEC: return this.VisitIncDec(eNode, context); - case EQUALITY: return this.VisitEquality(eNode, context); - case DECISION: return this.VisitDecision(eNode, context); - case METHODCALL: return this.VisitMethodCall(eNode, context); - case NEW: return this.VisitNew(eNode, context); - case JSONASSIGN: return this.VisitJsonAssign(eNode, context); - case ARRAYACCESS: return this.VisitArrayAccess(eNode, context); - default: - Guard.raise("Type isn't implemented: " + eNode.type); - } - }, - - VisitBinary: function (eNode, context) { - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - if (left === eNode.left && right === eNode.right && (left.executable && right.executable == eNode.executable)) - return eNode; - return $data.Expressions.ExpressionNodeTypes.BinaryExpressionNode.create(left.executable && right.executable, eNode.operator, left, right); - }, - VisitUnary: function (eNode, context) { - var operand = this.Visit(eNode.operand, context); - if (operand === eNode.operand) - return eNode; - return $data.Expressions.ExpressionNodeTypes.UnaryExpressionNode.create(operand.executable, eNode.operator, operand); - }, - VisitIncDec: function (eNode, context) { - var operand = this.Visit(eNode.operand, context); - if (operand === eNode.operand) - return eNode; - return $data.Expressions.ExpressionNodeTypes.IncDecExpressionNode.create(operand.executable, eNode.operator, operand, eNode.suffix); - }, - VisitEquality: function (eNode, context) { - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - if (left === eNode.left && right === eNode.right && (left.executable && right.executable == eNode.executable)) - return eNode; - return $data.Expressions.ExpressionNodeTypes.EqualityExpressionNode.create(left.executable && right.executable, eNode.operator, left, right); - }, - VisitDecision: function (eNode, context) { - var expression = this.Visit(eNode.expression, context); - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - if (expression === eNode.expression && left === eNode.left && right === eNode.right && (left.executable && right.executable && expression.executable == eNode.executable)) - return eNode; - return $data.Expressions.ExpressionNodeTypes.DecisionExpressionNode.create(left.executable && right.executable && expression.executable, expression, left, right); - }, - VisitMethodCall: function (eNode, context) { - var object = eNode.object ? this.Visit(eNode.object, context) : null; - var args = this.VisitArray(eNode.args, context); - if (object === eNode.object && args === eNode.args && ((object == null ? true : object.executable) == eNode.executable)) - return eNode; - return $data.Expressions.ExpressionNodeTypes.MethodcallExpressionNode.create(object == null ? true : object.executable, object, eNode.method, args); - }, - VisitNew: function (eNode, context) { - // { type:NEW, executable:true, values: [] }; - var values = this.VisitArray(eNode.values, context); - if (values === eNode.values) - return eNode; - return $data.Expressions.ExpressionNodeTypes.NewExpressionNode.create(true, values); - }, - VisitJsonAssign: function (eNode, context) { - // { type:JSONASSIGN, executable:true, left: variable, right: right } - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - if (left === eNode.left && right === eNode.right) - return eNode; - left.JSONASSIGN = true; - right.JSONASSIGN = true; - return $data.Expressions.ExpressionNodeTypes.JsonAssignExpressionNode.create(true, left, right); - }, - VisitArrayAccess: function (eNode, context) { - // { type:ARRAYACCESS, executable:true, array:, index: } - var array = this.Visit(eNode.array, context); - var index = this.Visit(eNode.index, context); - if (array === eNode.array && index === eNode.index) - return eNode; - return $data.Expressions.ExpressionNodeTypes.ArrayAccessExpressionNode.create(true, array, index); - }, - VisitArray: function (eNodes, context) { - var args = []; - var ok = true; - for (var i = 0; i < eNodes.length; i++) { - args[i] = this.Visit(eNodes[i], context); - ok = ok && args[i] === eNodes[i]; - } - return ok ? eNodes : args; - }, - - VisitLiteral: function (eNode, context) { - return { type: eNode.type, executable: true, value: eNode.value, valueType: eNode.valueType }; - }, - VisitVariable: function (eNode, context) { - if (typeof context.paramContext[eNode.name] == undefined) // isn't param //TODO: check ParamContext - Guard.raise("Variable is not defined in the paramContext: " + eNode.name); - //this._setExecutable(eNode, true); - return $data.Expressions.ExpressionNodeTypes.VariableExpressionNode.create(true, "Math", "GLOBALOBJECT"); - }, - VisitMember: function (eNode, context) { - var chain = this.GetMemberChain(eNode); - var firstMember = chain[0].name; - var isLambdaParam = context.lambdaParams.indexOf(firstMember) >= 0; - var isLocalParam = firstMember == context.paramsName; //TODO: check ParamContext // old: typeof context.paramContext[firstMember] != "undefined"; - if (!isLocalParam && !isLambdaParam) - Guard.raise("Variable is not defined in the paramContext or the lambda parameters: " + firstMember); - - return $data.Expressions.ExpressionNodeTypes.MemberAccessExpressionNode.create(isLocalParam, eNode.expression, eNode.member); - } -}, null);$data.Class.define('$data.Expressions.ExecutorVisitor', $data.Expressions.ExpTreeVisitor, null, -{ - //-- - VisitVariable: function (eNode, context) { - if (!eNode.executable) - return eNode; - var value = (eNode.name == context.paramsName) ? context.paramContext : window[eNode.name]; - if (typeof value == 'undefined') - Guard.raise( - new Exception("Unknown variable in '" + context.operation + "' operation. The variable isn't referenced in the parameter context and it's not a global variable: '" + eNode.name + "'.", - "InvalidOperation", { operationName: context.operation, missingParameterName: eNode.name }) - ); - return $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, typeof value, value); - }, - VisitMember: function (eNode, context) { - if (!eNode.executable) - return eNode; - var chain = this.GetMemberChain(eNode); - var value; - for (var i = 0; i < chain.length; i++) { - if (i == 0) - value = context.paramContext; - else - value = value[chain[i].name]; - } - return $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, typeof value, value); - - - }, - VisitUnary: function (eNode, context) { - var operand = this.Visit(eNode.operand, context); - if (operand !== eNode.operand) - eNode = $data.Expressions.ExpressionNodeTypes.UnaryExpressionNode.create(eNode.executable, eNode.operator, operand); - if (!eNode.executable) - return eNode; - // executing and returning with result as a literal - var value; - var src; - var operandValue = ((operand.valueType == "string") ? ("'" + operand.value + "'") : operand.value); - src = "value = " + eNode.operator + " " + operandValue; - eval(src); - - return $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, typeof value, value); - }, - VisitIncDec: function (eNode, context) { - var operand = this.Visit(eNode.operand, context); - if (operand !== eNode.operand) - eNode = $data.Expressions.ExpressionNodeTypes.IncDecExpressionNode.create(eNode.executable, eNode.operator, operand, eNode.suffix); - if (!eNode.executable) - return eNode; - // executing and returning with result as a literal - var value; - if (eNode.suffix) - value = eNode.operator == "++" ? operand.value++ : operand.value--; - else - value = eNode.operator == "++" ? ++operand.value : --operand.value; - return $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, typeof value, value); - }, - VisitBinary: function (eNode, context) { - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - if (left !== eNode.left || right !== eNode.right) - eNode = $data.Expressions.ExpressionNodeTypes.BinaryExpressionNode.create(eNode.executable, eNode.operator, left, right); - if (!eNode.executable) - return eNode; - // executing and returning with result as a literal - var value; - var src; - var leftValue = ((left.valueType == "string") ? ("'" + left.value + "'") : left.value); - var rightValue = ((right.valueType == "string") ? ("'" + right.value + "'") : right.value); - src = "value = " + leftValue + " " + eNode.operator + " " + rightValue; - eval(src); - - return $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, typeof value, value); - }, - VisitEquality: function (eNode, context) { - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - if (left !== eNode.left || right !== eNode.right) - eNode = $data.Expressions.ExpressionNodeTypes.EqualityExpressionNode.create(eNode.executable, eNode.operator, left, right); - if (!eNode.executable) - return eNode; - // executing and returning with result as a literal - var value; - var src; - var leftValue = ((left.valueType == "string") ? ("'" + left.value + "'") : left.value); - var rightValue = ((right.valueType == "string") ? ("'" + right.value + "'") : right.value); - src = "value = " + leftValue + " " + eNode.operator + " " + rightValue; - eval(src); - return $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, typeof value, value); - }, - VisitDecision: function (eNode, context) { - var expression = this.Visit(eNode.expression, context); - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - if (expression !== eNode.expression || left !== eNode.left || right !== eNode.right) - eNode = $data.Expressions.ExpressionNodeTypes.DecisionExpressionNode.create(eNode.executable, expression, left, right); - if (!eNode.executable) - return eNode; - // executing and returning with result as a literal - var value = expression.value ? left.value : right.value; - return $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, typeof value, value); - }, - VisitMethodCall: function (eNode, context) { - var object = eNode.object ? this.Visit(eNode.object, context) : null; - var args = this.VisitArray(eNode.args, context); - if (object !== eNode.object || args != eNode.args) - eNode = $data.Expressions.ExpressionNodeTypes.MethodcallExpressionNode.create(eNode.executable, object, eNode.method, args); - if (!eNode.executable) - return eNode; - // executing and returning with result as a literal - var a = []; - for (var i = 0; i < args.length; i++) { - var arg = args[i]; - var t = typeof arg.value; - a.push((t == "string") ? ("'" + arg.value + "'") : arg.value); - } - var value; - var src = object ? - "value = object.value[eNode.method](" + a.join(",") + ");" - : - "value = " + eNode.method + "(" + a.join(",") + ");"; - eval(src); - - return $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, typeof value, value); - }, - VisitArrayAccess: function (eNode, context) { - // { type:ARRAYACCESS, executable:true, array:, index: } - var arrayNode = this.Visit(eNode.array, context); - var indexNode = this.Visit(eNode.index, context); - var value = arrayNode.value[indexNode.value]; - return $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, typeof value, value); - } -}, null); $data.Class.define('$data.Expressions.ExpressionBuilder', null, null, -{ - constructor: function (context) { - this.context = context; - }, - _isLambdaParam: function (name) { - var p = this.context.lambdaParams; - for (var i = 0; i < p.length; i++) { - if (p[i] == name) - return true; - } - return false; - }, - _isParam: function (name) { - return this.context.paramContext[name] != undefined; - }, - _isParamRoot: function (name) { - return this.context.paramsName == name; - }, - Build: function (node, expNode) { - var n; - switch (node.arity) { - case "infix": - if ("(" == node.value) - n = this.BuildMethodCall(node, expNode); - else if ("." == node.value) - n = this.BuildMember(node, expNode); - else if (["===", "==", "!==", "!=", ">", "<", ">=", "<="].indexOf(node.value) >= 0) - n = this.BuildEquality(node, expNode); - else if (["&&", "||"].indexOf(node.value) >= 0) - n = this.BuildBinary(node, expNode); - else if (["+", "-", "*", "/", "%"].indexOf(node.value) >= 0) - n = this.BuildBinary(node, expNode); - else if ("[" == node.value) - n = this.BuildArrayAccess(node, expNode); - else - Guard.raise("Value of infix node isn't implemented: " + node.value); - break; - case "prefix": - if (["+", "-", "!"].indexOf(node.value) >= 0) - n = this.BuildUnary(node, expNode); - else if (["++", "--"].indexOf(node.value) >= 0) - n = this.BuildIncDec(node, expNode); - else if ("{" == node.value/* && "object" == node.type*/) //TODO: check the second condition necessity - n = this.BuildNewExpression(node, expNode); - else - Guard.raise("Value of prefix node isn't implemented: " + node.value); - break; - case "suffix": - if (["++", "--"].indexOf(node.value) >= 0) - n = this.BuildIncDec(node, expNode); - else - Guard.raise("Value of suffix node isn't implemented: " + node.value); - break; - case "string": - case "number": - n = this.BuildLiteral(node, expNode); //TODO: more arity to literal? - break; - case "ternary": - if (node.value == "?") - n = this.BuildDecision(node, expNode); - else - Guard.raise("Value of ternary node isn't implemented: " + node.value); - break; - case null: - case undefined: - if (node.type == "boolean" && (node.value == "true" || node.value == "false")) - n = this.BuildBoolLiteral(node, expNode); - else - n = this.BuildVariable(node, expNode); - break; - default: - Guard.raise("Arity isn't implemented: " + node.arity); - } - return n; - }, - BuildNewExpression: function (node, expNode) { - var newExpression = $data.Expressions.ExpressionNodeTypes.NewExpressionNode.create(true, []); - var n = node.first; - for (var i = 0; i < n.length; i++) - newExpression.values.push(this.Build(n[i], newExpression)); - return newExpression; - }, - BuildLiteral: function (node, expNode) { - return $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, node.arity, node.value); - }, - BuildBoolLiteral: function (node, expNode) { - return $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, node.type, node.value == "true" ? true : false); - }, - BuildVariable: function (node, expNode) { - if (!node.first) { - if (expNode.type == MEMBERACCESS) { - var subType; - if (this._isLambdaParam(node.value)) - subType = "LAMBDAPARAM"; - else if (this._isParamRoot(node.value)) - subType = "PARAMETERROOT"; - else if (this._isParam(node.value)) - subType = "PARAMETER"; - else - subType = "PROPERTY"; - } - else { - if (this._isLambdaParam(node.value)) - subType = "LAMBDAPARAM"; - else if (this._isParamRoot(node.value)) - subType = "PARAMETERROOT"; - else if (this._isParam(node.value)) - subType = "PARAMETER"; - else if (window[node.value] != undefined) - subType = "GLOBALOBJECT"; - else - Guard.raise( - new Exception("Unknown variable in '" + this.context.operation + "' operation. The variable isn't referenced in the parameter context and it's not a global variable: '" + node.value + "'.", - "InvalidOperation", { operationName: this.context.operation, missingParameterName: node.value }) - ); - } - return $data.Expressions.ExpressionNodeTypes.VariableExpressionNode.create(true, node.value, subType); - } - - var left = $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, "name", node.value); - - var jsonAssign = $data.Expressions.ExpressionNodeTypes.JsonAssignExpressionNode.create(true); - var right = this.Build(node.first, jsonAssign); - //left.parent = jsonAssign; - jsonAssign.left = left; - jsonAssign.right = right; - - left.JSONASSIGN = true; - right.JSONASSIGN = true; - - return jsonAssign; - }, - BuildMember: function (node, expNode) { - if (node.value != "." || node.arity != "infix") { - if (node.type == "string") { //TODO: more types? - return $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, node.arity, node.value); - } - return $data.Expressions.ExpressionNodeTypes.MemberAccessExpressionNode.create(true, null, node.value); - } - var result = $data.Expressions.ExpressionNodeTypes.MemberAccessExpressionNode.create(true); - var expression = this.Build(node.first, result); - var member = this.Build(node.second, result); - result.expression = expression; - result.member = member; - return result; - }, - BuildUnary: function (node, expNode) { - var result = $data.Expressions.ExpressionNodeTypes.UnaryExpressionNode.create(true, node.value); - result.operand = this.Build(node.first, result); - return result; - }, - BuildIncDec: function (node, expNode) { - var result = $data.Expressions.ExpressionNodeTypes.IncDecExpressionNode.create(true, node.value, null, node.arity == "suffix"); - result.operand = this.Build(node.first, result); - return result; - }, - BuildBinary: function (node, expNode) { - if (!node.first) Guard.raise("Cannot build binary: node.first is null"); - if (!node.second) Guard.raise("Cannot build binary: node.second is null"); - var result = $data.Expressions.ExpressionNodeTypes.BinaryExpressionNode.create(true, node.value); - result.left = this.Build(node.first, result); - result.right = this.Build(node.second, result); - return result; - }, - BuildEquality: function (node, expNode) { - var result = $data.Expressions.ExpressionNodeTypes.EqualityExpressionNode.create(true, node.value); - result.left = this.Build(node.first, result); - result.right = this.Build(node.second, result); - return result; - }, - BuildDecision: function (node, expNode) { - var result = $data.Expressions.ExpressionNodeTypes.DecisionExpressionNode.create(true); - result.expression = this.Build(node.first, result); - result.left = this.Build(node.second, result); - result.right = this.Build(node.third, result); - return result; - }, - BuildMethodCall: function (node, expNode) { - var result = $data.Expressions.ExpressionNodeTypes.MethodcallExpressionNode.create(true); - if (node.first.type == "function") { - //-- object's function - result.object = this.Build(node.first.first, result); - result.method = node.first.second.value; - } - else { - //-- global function - if (node.first.type != null) - Guard.raise("Cannot build MethodCall because type is " + type); - result.object = null; - result.method = node.first.value; - } - var argNodes = node.second; - var args = []; - for (var i = 0; i < argNodes.length; i++) { - var arg = argNodes[i]; - args[i] = this.Build(arg, result); - } - result.args = args; - return result; - }, - BuildArrayAccess: function (node, expNode) { - // { type:ARRAYACCESS, executable:true, array:, index: } - var result = $data.Expressions.ExpressionNodeTypes.ArrayAccessExpressionNode.create(true); - result.array = this.Build(node.first, result); - result.index = this.Build(node.second, result); - return result; - } -}, null);$C('$data.Expressions.AssociationInfoExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (associationInfo) { - this.associationInfo = associationInfo; - }, - nodeType: { value: $data.Expressions.ExpressionType.AssociationInfo, enumerable: true } -});$C('$data.Expressions.CodeExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (source, parameters) { - if (Container.resolveType(Container.getTypeName(source)) == $data.String && source.replace(/^[\s\xA0]+/, "").match("^function") != "function") { - source = "function (it) { return " + source + "; }"; - } - - this.source = source; - this.parameters = parameters; - }, - nodeType: { value: $data.Expressions.ExpressionType.Code, enumerable: true } -});$C('$data.Expressions.CodeToEntityConverter', $data.Expressions.ExpressionVisitor, null, { - constructor: function (scopeContext) { - ///This visitor converts a JS language tree into a semantical Entity Expression Tree This visitor should be invoked on a CodeExpression - ///context.thisArg contains parameters, context.lambdaParams should have an array value - this.scopeContext = scopeContext; - this.parameters = []; - - }, - - - VisitBinary: function (expression, context) { - var left = this.Visit(expression.left, context); - var right = this.Visit(expression.right, context); - - if ((!(left instanceof $data.Expressions.ConstantExpression) && right instanceof $data.Expressions.ConstantExpression) || - (!(right instanceof $data.Expressions.ConstantExpression) && left instanceof $data.Expressions.ConstantExpression)) { - - var refExpression, constExpr; - if (right instanceof $data.Expressions.ConstantExpression) { - refExpression = left; - constExpr = right; - } else { - refExpression = right; - constExpr = left; - } - - var memInfo; - if ((memInfo = refExpression.selector) instanceof $data.Expressions.MemberInfoExpression || - (memInfo = refExpression.operation) instanceof $data.Expressions.MemberInfoExpression) { - - - if (memInfo.memberDefinition && (memInfo.memberDefinition.type || memInfo.memberDefinition.dataType)) { - var fieldType = Container.resolveType(memInfo.memberDefinition.type || memInfo.memberDefinition.dataType); - var constExprType = Container.resolveType(constExpr.type); - - if (fieldType !== constExprType) { - - var value = constExpr.value; - if (expression.operator === $data.Expressions.ExpressionType.In) { - if (Array.isArray(value)) { - var resultExp = []; - for (var i = 0; i < value.length; i++) { - resultExp.push(new $data.Expressions.ConstantExpression(value[i], fieldType)); - } - value = resultExp; - fieldType = $data.Array; - } else { - fieldType = constExprType; - } - } - - if (right === constExpr) { - right = new $data.Expressions.ConstantExpression(value, fieldType, right.name); - } else { - left = new $data.Expressions.ConstantExpression(value, fieldType, left.name); - } - } - } - } - } - - var operatorResolution = this.scopeContext.resolveBinaryOperator(expression.nodeType, expression, context.frameType); - var result = Container.createSimpleBinaryExpression(left, right, expression.nodeType, expression.operator, expression.type, operatorResolution); - return result; - }, - - VisitUnary: function (expression, context) { - var operand = this.Visit(expression.operand, context); - var operatorResolution = this.scopeContext.resolveUnaryOperator(expression.nodeType, expression, context.frameType); - var result = Container.createUnaryExpression(operand, expression.operator, expression.nodeType, operatorResolution); - return result; - }, - - VisitParameter: function (expression, context) { - Guard.requireValue("context", context); - var et = $data.Expressions.ExpressionType; - switch (expression.nodeType) { - case et.LambdaParameterReference: - var result = Container.createEntityExpression(context.lambdaParameters[expression.paramIndex], { lambda: expression.name }); - return result; - case et.LambdaParameter: - //TODO: throw descriptive exception or return a value - break; - default: - Guard.raise("Global parameter " + expression.name + " not found. For query parameters use 'this.field' notation"); - break; - } - }, - - VisitThis: function (expression, context) { - ///converts the ThisExpression into a QueryParameterExpression tha't value will be evaluated and stored in this.parameters collection - var index = this.parameters.push({ name: "", value: undefined }) - 1; - var result = Container.createQueryParameterExpression("", index, context.queryParameters, undefined); - return result; - }, - - VisitFunction: function (expression, context) { - var result = $data.Expressions.ExpressionVisitor.prototype.VisitFunction.apply(this, arguments); - return result.body; - }, - - VisitCall: function (expression, context) { - //var exp = this.Visit(expression.expression); - var self = this; - var exp = this.Visit(expression.expression, context); - var member = this.Visit(expression.member, context); - var args = expression.args.map(function (arg) { - return self.Visit(arg, context); - }); - var result; - - ///filter=>function(p) { return p.Title == this.xyz.BogusFunction('asd','basd');} - switch (true) { - case exp instanceof $data.Expressions.QueryParameterExpression: - var argValues = args.map(function (a) { return a.value; }); - result = expression.implementation(exp.value, member.value, argValues); - //var args = expressions - return Container.createQueryParameterExpression(exp.name + "$" + member.value, exp.index, result, typeof result); - case exp instanceof $data.Expressions.EntityFieldExpression: - - case exp instanceof $data.Expressions.EntityFieldOperationExpression: - var operation = this.scopeContext.resolveFieldOperation(member.value, exp, context.frameType); - if (!operation) { - Guard.raise("Unknown entity field operation: " + member.getJSON()); - } - member = Container.createMemberInfoExpression(operation); - result = Container.createEntityFieldOperationExpression(exp, member, this._resolveFunctionArguments(args, operation.parameters)); - return result; - - case exp instanceof $data.Expressions.EntitySetExpression: - var operation = this.scopeContext.resolveSetOperations(member.value, exp, context.frameType); - if (!operation) { - Guard.raise("Unknown entity field operation: " + member.getJSON()); - } - member = Container.createMemberInfoExpression(operation); - result = Container.createFrameOperationExpression(exp, member, this._resolveFunctionArguments(args, operation.parameters)); - return result; - - case exp instanceof $data.Expressions.EntityExpression: - var operation = this.scopeContext.resolveTypeOperations(member.value, exp, context.frameType); - if (!operation) { - Guard.raise("Unknown entity function operation: " + member.getJSON()); - } - - member = Container.createMemberInfoExpression(operation); - result = Container.createEntityFunctionOperationExpression(exp, member, this._resolveFunctionArguments(args, operation.method.params)); - return result; - break; - case exp instanceof $data.Expressions.EntityContextExpression: - var operation = this.scopeContext.resolveContextOperations(member.value, exp, context.frameType); - if (!operation) { - Guard.raise("Unknown entity function operation: " + member.getJSON()); - } - - member = Container.createMemberInfoExpression(operation); - result = Container.createContextFunctionOperationExpression(exp, member, this._resolveFunctionArguments(args, operation.method.params)); - return result; - break; - default: - Guard.raise("VisitCall: Only fields can have operations: " + expression.getType().name); - //TODO we must not alter the visited tree - } - - }, - _resolveFunctionArguments: function (args, params) { - if (params) // remove current field poz - params = params.filter(function (p, i) { return p.name !== '@expression'; }); - - //objectArgs - if (args.length === 1 && args[0] instanceof $data.Expressions.ConstantExpression && typeof args[0].value === 'object' && args[0].value && params && params[0] && - args[0].value.constructor === $data.Object && params.some(function (param) { return param.name in args[0].value })) { - - return params.map(function (p) { - var type = p.type || p.dataType || args[0].type; - return new $data.Expressions.ConstantExpression(args[0].value[p.name], Container.resolveType(type), p.name); - }); - - } else { - return args.map(function (expr, i) { - if (expr instanceof $data.Expressions.ConstantExpression && params && params[i]) { - var type = params[i].type || params[i].dataType || expr.type; - return new $data.Expressions.ConstantExpression(expr.value, Container.resolveType(type), params[i].name); - } else { - return expr; - } - }); - } - }, - - VisitProperty: function (expression, context) { - /// - var exp = this.Visit(expression.expression, context); - var member = this.Visit(expression.member, context); - - //Guard.requireType("member", member, $data.Expressions.ConstantExpression); - Guard.requireType("member", member, $data.Expressions.ConstantExpression); - - function isPrimitiveType(memberDefinitionArg) { - - var t = memberDefinitionArg.dataType; - if (typeof t === 'function') { return false; } - - // suspicious code - /*switch (t) { - //TODO: implement this - }*/ - } - - switch (exp.expressionType) { - case $data.Expressions.EntityExpression: - var memberDefinition = exp.getMemberDefinition(member.value); - if (!memberDefinition) { - Guard.raise(new Exception("Unknown member: " + member.value, "MemberNotFound")); - } - //var storageMemberDefinition = - var storageField = memberDefinition.storageModel - .PhysicalType.memberDefinitions.getMember(memberDefinition.name); - var res; - var memberDefinitionExp; - switch (storageField.kind) { - case "property": - memberDefinitionExp = Container.createMemberInfoExpression(memberDefinition); - res = Container.createEntityFieldExpression(exp, memberDefinitionExp); - return res; - case "navProperty": - var assocInfo = memberDefinition.storageModel.Associations[memberDefinition.name]; - var setExpression = Container.createEntitySetExpression(exp, Container.createAssociationInfoExpression(assocInfo)); - if (assocInfo.ToMultiplicity !== "*") { - var ee = Container.createEntityExpression(setExpression, {}); - return ee; - }/* else { - context.lambdaParameters.push(setExpression); - }*/ - return setExpression; - case "complexProperty": - memberDefinitionExp = Container.createMemberInfoExpression(memberDefinition); - res = Container.createComplexTypeExpression(exp, memberDefinitionExp); - return res; - //TODO: missing default case - } - - //s/switch => property or navigationproperty - case $data.Expressions.ComplexTypeExpression: - var memDef = exp.getMemberDefinition(member.value); - if (!(memDef)) { - Guard.raise("Unknown member " + member.value + " on " + exp.entityType.name); - } - var memDefExp = Container.createMemberInfoExpression(memDef); - var result; - //TODO!!!! - if (Container.isPrimitiveType(Container.resolveType(memDef.dataType))) { - result = Container.createEntityFieldExpression(exp, memDefExp); - return result; - } - result = Container.createComplexTypeExpression(exp, memDefExp); - return result; - case $data.Expressions.QueryParameterExpression: - var value = expression.implementation(exp.value, member.value); - this.parameters[exp.index].name += "$" + member.value; - this.parameters[exp.index].value = value; - return Container.createQueryParameterExpression(exp.name + "$" + member.value, exp.index, value, Container.getTypeName(value)); - case $data.Expressions.EntityFieldExpression: - case $data.Expressions.EntityFieldOperationExpression: - var operation = this.scopeContext.resolveFieldOperation(member.value, exp, context.frameType); - if (!operation) { - Guard.raise("Unknown entity field operation: " + member.getJSON()); - } - member = Container.createMemberInfoExpression(operation); - result = Container.createEntityFieldOperationExpression(exp, member, []); - - return result; - default: - Guard.raise("Unknown expression type to handle: " + exp.expressionType.name); - } - } -});$C('$data.Expressions.ComplexTypeExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (source, selector) { - /// - /// - /// - /// - /// - /// - /// - /// - Guard.requireType("source", source, [$data.Expressions.EntityExpression, $data.Expressions.ComplexTypeExpression]); - Guard.requireType("selector", selector, [$data.Expressions.EntityExpression, $data.Expressions.MemberInfoExpression]); - this.source = source; - this.selector = selector; - var dt = source.entityType.getMemberDefinition(selector.memberName).dataType; - var t = Container.resolveType(dt); - this.entityType = t; - }, - - getMemberDefinition: function (name) { - return this.entityType.getMemberDefinition(name); - }, - - nodeType: { value: $data.Expressions.ExpressionType.Com } -}); - -$C('$data.Expressions.EntityContextExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (instance) { - /// - //Object.defineProperty(this, "instance", { value: instance, enumerable: false }); - this.instance = instance; - //this.storage_type = {}; - //this.typeName = this.type.name; - }, - instance: { enumerable: false }, - nodeType : { value: $data.Expressions.ExpressionType.EntityContext, enumerable: true } - -}); -$C('$data.Expressions.EntityExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (source, selector) { - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - Guard.requireValue("source", source); - Guard.requireValue("selector", selector); - if (!(source instanceof $data.Expressions.EntitySetExpression) && !(source instanceof $data.Expressions.ServiceOperationExpression)) { - Guard.raise("Only EntitySetExpressions can be the source for an EntityExpression"); - } - - this.source = source; - this.selector = selector; - - this.entityType = this.source.elementType; - this.storageModel = this.source.storageModel; - - Guard.requireValue("entityType", this.entityType); - Guard.requireValue("storageModel", this.storageModel); - - }, - - getMemberDefinition: function (name) { - var memdef = this.entityType.getMemberDefinition(name); - if (!(memdef)) { - Guard.raise(new Exception("Unknown member " + name + " on type "+ this.entityType.name, "MemberNotFound")); - }; - memdef.storageModel = this.storageModel; - return memdef; - }, - - nodeType: { value: $data.Expressions.ExpressionType.Entity } -});$C('$data.Expressions.EntityExpressionVisitor', null, null, { - - constructor: function () { - this.lambdaTypes = []; - }, - - canVisit: function (expression) { - return expression instanceof $data.Expressions.ExpressionNode; - }, - - Visit: function (expression, context) { - if (!this.canVisit(expression)) - return expression; - - var visitorName = "Visit" + expression.getType().name; - if (visitorName in this) { - var fn = this[visitorName]; - var result = fn.call(this, expression, context); - if (typeof result === 'undefined') { - return expression; - } - return result; - } - //console.log("unhandled expression type:" + expression.getType().name); - return expression; - }, - VisitToArrayExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - if (source !== expression.source) { - return Container.createToArrayExpression(source); - } - return expression; - }, - VisitForEachExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - if (source !== expression.source) { - return Container.createForEachExpression(source); - } - return expression; - }, - VisitMemberInfoExpression: function (expression, context) { - return expression; - }, - - VisitSingleExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - if (source !== expression.source) - return Container.createSingleExpression(source); - return expression; - }, - - VisitFirstExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - if (source !== expression.source) - return Container.createFirstExpression(source); - return expression; - }, - - VisitSomeExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - if (source !== expression.source) - return Container.createSomeExpression(source); - return expression; - }, - - VisitFindExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - if (source !== expression.source) - return Container.createFindExpression(source); - return expression; - }, - - VisitEveryExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - if (source !== expression.source) - return Container.createEveryExpression(source); - return expression; - }, - - VisitCountExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - if (source !== expression.source) - return Container.createCountExpression(source); - return expression; - }, - - VisitBatchDeleteExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - if (source !== expression.source) { - return Container.createBatchDeleteExpression(source); - } - return expression; - }, - - VisitObjectLiteralExpression: function (expression, context) { - var newValues = expression.members.map(function (ofe) { - return this.Visit(ofe, context); - }, this); - var equal = true; - for (var i = 0; i < expression.members.length; i++) { - equal = equal && (expression.members[i] === newValues[i]); - } - if (!equal) { - return Container.createObjectLiteralExpression(newValues); - } - return expression; - }, - VisitObjectFieldExpression: function (expression, context) { - var newExpression = this.Visit(expression.expression, context); - if (expression.expression !== newExpression) { - return Container.createObjectFieldExpression(expression.fieldName, newExpression); - } - return expression; - }, - VisitIncludeExpression: function (expression, context) { - var newExpression = this.Visit(expression.source, context); - if (newExpression !== expression.source) { - return Container.createIncludeExpression(newExpression, expression.selector); - } - return expression; - }, - - VisitUnaryExpression: function(expression, context) { - - /// - /// - var operand = this.Visit(expression.operand, context); - if (expression.operand !== operand) { - return Container.createUnaryExpression(operand, expression.operator, expression.nodeType, expression.resolution); - }; - return expression; - }, - - VisitSimpleBinaryExpression: function (expression, context) { - /// - /// - /// - // - var left = this.Visit(expression.left, context); - var right = this.Visit(expression.right, context); - if (left !== expression.left || right !== expression.right) { - return new $data.Expressions.SimpleBinaryExpression(left, right, expression.nodeType, - expression.operator, expression.type, expression.resolution); - } - return expression; - }, - - VisitEntityContextExpression: function (expression, context) { - return expression; - }, - - VisitCodeExpression: function (expression, context) { - /// - /// - /// - return expression; - }, - - VisitComplexTypeExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - var selector = this.Visit(expression.selector, context); - if (source !== expression.source || selector !== expression.selector) { - var result = Container.createComplexTypeExpression(source, selector); - return result; - } - return expression; - }, - - VisitEntityExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - var selector = this.Visit(expression.selector, context); - if (source !== expression.source || selector !== expression.selector) { - var result = Container.createEntityExpression(source, selector); - return result; - } - return expression; - }, - - VisitEntityFieldExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - var selector = this.Visit(expression.selector, context); - if (source !== expression.source || selector !== expression.selector) { - var result = Container.createEntityFieldExpression(source, selector); - return result; - } - return expression; - }, - - VisitEntityFieldOperationExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - var operation = this.Visit(expression.operation, context); - var parameters = expression.parameters.map(function (p) { - return this.Visit(p); - }, this); - var result = Container.createEntityFieldOperationExpression(source, operation, parameters); - return result; - }, - - VisitParametricQueryExpression: function (expression, context) { - var exp = this.Visit(expression.expression, context); - var args = expression.parameters.map(function (p) { - return this.Visit(p); - }, this); - var result = Container.createParametricQueryExpression(exp, args); - return result; - }, - - VisitEntitySetExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - var selector = this.Visit(expression.selector, context); - if (source !== expression.source || selector !== expression.selector) { - return Container.createEntitySetExpression(source, selector, expression.params, expression.instance); - } - return expression; - }, - - VisitInlineCountExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - var selector = this.Visit(expression.selector, context); - if (source !== expression.source || selector !== expression.selector) { - return Container.createInlineCountExpression(source, selector, expression.params, expression.instance); - } - return expression; - }, - - VisitFilterExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - var selector = this.Visit(expression.selector, context); - if (source !== expression.source || selector !== expression.selector) { - return Container.createFilterExpression(source, selector, expression.params, expression.instance); - } - return expression; - }, - - VisitProjectionExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - var selector = this.Visit(expression.selector, context); - if (source !== expression.source || selector !== expression.selector) { - var expr = Container.createProjectionExpression(source, selector, expression.params, expression.instance); - expr.projectionAs = expression.projectionAs; - return expr; - } - return expression; - }, - - VisitOrderExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - var selector = this.Visit(expression.selector, context); - if (source !== expression.source || selector !== expression.selector) { - return Container.createOrderExpression(source, selector, expression.nodeType); - } - return expression; - }, - VisitPagingExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - var amount = this.Visit(expression.amount, context); - if (source !== expression.source || amount !== expression.amount) { - return Container.createPagingExpression(source, amount, expression.nodeType); - } - return expression; - } -}); -$C('$data.Expressions.ExpressionMonitor', $data.Expressions.EntityExpressionVisitor, null, { - constructor: function (monitorDefinition) { - this.Visit = function (expression, context) { - - var result = expression; - var methodName; - if (this.canVisit(expression)) { - - //if (monitorDefinition.FilterExpressionNode) { - - //}; - - if (monitorDefinition.VisitExpressionNode) { - monitorDefinition.VisitExpressionNode.apply(monitorDefinition, arguments); - }; - - methodName = "Visit" + expression.getType().name; - if (methodName in monitorDefinition) { - result = monitorDefinition[methodName].apply(monitorDefinition, arguments); - } - } - - - //apply is about 3-4 times faster then call on webkit - - var args = arguments; - if (result !== expression) args = [result, context]; - result = $data.Expressions.EntityExpressionVisitor.prototype.Visit.apply(this, args); - - args = [result, context]; - - if (this.canVisit(result)) { - var expressionTypeName = result.getType().name; - if (monitorDefinition.MonitorExpressionNode) { - monitorDefinition.MonitorExpressionNode.apply(monitorDefinition, args); - } - methodName = "Monitor" + expressionTypeName; - if (methodName in monitorDefinition) { - monitorDefinition[methodName].apply(monitorDefinition, args); - } - - if (monitorDefinition.MutateExpressionNode) { - monitorDefinition.MutateExpressionNode.apply(monitorDefinition, args); - } - methodName = "Mutate" + expressionTypeName; - if (methodName in monitorDefinition) { - result = monitorDefinition[methodName].apply(monitorDefinition, args); - } - - } - return result; - }; - } -});$C('$data.Expressions.EntityFieldExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (source, selector) { - /// - /// - this.selector = selector; - this.source = source; - - - if (this.selector instanceof $data.Expressions.MemberInfoExpression || this.selector.name) { - this.memberName = this.selector.name; - } - }, - - nodeType: { value: $data.Expressions.ExpressionType.EntityField } -}); - -$C('$data.Expressions.EntityFieldOperationExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (source, operation, parameters) { - this.source = source; - this.operation = operation; - this.parameters = parameters; - }, - nodeType: { value: $data.Expressions.ExpressionType.EntityFieldOperation } - -});$C('$data.Expressions.EntitySetExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (source, selector, params, instance) { - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - Guard.requireType("source", source, - [$data.Expressions.EntityContextExpression, $data.Expressions.EntitySetExpression]); - Guard.requireType("selector", source, - [$data.Expressions.MemberInfoExpression, $data.Expressions.CodeExpression, $data.Expressions.ParametricQueryExpression]); - - this.source = source; - this.selector = selector; - this.params = params; - //Object.defineProperty(this, "instance", { value: instance, enumerable: false, writable: true }); - this.instance = instance; - - function findContext() { - //TODO: use source from function parameter and return a value at the end of the function - var r = source; - while (r) { - if (r instanceof $data.Expressions.EntityContextExpression) { - return r; - } - r = r.source; - } - } - - ///TODO!!! - this.storage_type = {}; - var c = findContext(); - switch (true) { - case this.source instanceof $data.Expressions.EntityContextExpression: - Guard.requireType("selector", selector, $data.Expressions.MemberInfoExpression); - this.elementType = selector.memberDefinition.elementType; - this.storageModel = c.instance._storageModel.getStorageModel(this.elementType); - break; - case this.source instanceof $data.Expressions.EntityExpression: - Guard.requireType("selector", selector, $data.Expressions.AssociationInfoExpression); - this.elementType = selector.associationInfo.ToType; - this.storageModel = c.instance._storageModel.getStorageModel(this.elementType); - break; - case this.source instanceof $data.Expressions.EntitySetExpression: - this.elementType = this.source.elementType; - this.storageModel = this.source.storageModel; - break; - case this.source instanceof $data.Expressions.ServiceOperationExpression: - this.elementType = this.source.elementType;//????????? - this.storageModel = this.source.storageModel; - break; - default: - Guard.raise("take and skip must be the last expressions in the chain!"); - //Guard.raise("Unknown source type for EntitySetExpression: " + this.getType().name); - break; - } - - // suspicious code - /*if (this.source instanceof $data.Expressions.EntitySetExpression) { - //TODO: missing operation - }*/ - //EntityTypeInfo - - }, - instance: { enumerable: false }, - nodeType: { value: $data.Expressions.ExpressionType.EntitySet, enumerable: true } -}); -$C('$data.Expressions.FrameOperationExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (source, operation, parameters) { - this.source = source; - this.operation = operation; - this.parameters = parameters; - }, - nodeType: { value: $data.Expressions.ExpressionType.FrameOperation } - -}); - -$C('$data.Expressions.EntityFunctionOperationExpression', $data.Expressions.FrameOperationExpression, null, { - nodeType: { value: $data.Expressions.ExpressionType.EntityFunctionOperation } -}); - -$C('$data.Expressions.ContextFunctionOperationExpression', $data.Expressions.FrameOperationExpression, null, { - nodeType: { value: $data.Expressions.ExpressionType.ContextFunctionOperation } -}); -$C('$data.Expressions.FilterExpression', $data.Expressions.EntitySetExpression, null, { - constructor: function (source, selector) { - /// - /// - /// - /// - /// - /// - /// - /// - this.resultType = $data.Array; - }, - nodeType: { value: $data.Expressions.ExpressionType.Filter, enumerable: true } -}); - -$C('$data.Expressions.InlineCountExpression', $data.Expressions.EntitySetExpression, null, { - constructor: function (source, selector) { - }, - nodeType: { value: $data.Expressions.ExpressionType.InlineCount, enumerable: true } -}); - -$C('$data.Expressions.FrameOperator', $data.Expressions.ExpressionNode, null, { - constructor: function () { - this.isTerminated = true; - } -}); - -$C('$data.Expressions.CountExpression', $data.Expressions.FrameOperator, null, { - constructor: function (source) { - /// - /// - /// - this.source = source; - this.resultType = $data.Integer; - }, - nodeType: { value: $data.Expressions.ExpressionType.Count, enumerable: true } -}); - -$C('$data.Expressions.SingleExpression', $data.Expressions.FrameOperator, null, { - constructor: function (source) { - /// - /// - /// - this.source = source; - this.resultType = $data.Object; - }, - nodeType: { value: $data.Expressions.ExpressionType.Single, enumerable: true } -}); - -$C('$data.Expressions.FindExpression', $data.Expressions.FrameOperator, null, { - constructor: function (source, params) { - /// - /// - /// - this.source = source; - this.params = params; - this.resultType = $data.Object; - }, - nodeType: { value: $data.Expressions.ExpressionType.Find, enumerable: true } -}); - -$C('$data.Expressions.FirstExpression', $data.Expressions.FrameOperator, null, { - constructor: function (source) { - /// - /// - /// - this.source = source; - this.resultType = $data.Object; - }, - nodeType: { value: $data.Expressions.ExpressionType.First, enumerable: true } -}); - -$C('$data.Expressions.ForEachExpression', $data.Expressions.FrameOperator, null, { - constructor: function (source) { - /// - /// - /// - this.source = source; - this.resultType = $data.Array; - }, - nodeType: { value: $data.Expressions.ExpressionType.ForEach, enumerable: true } -}); -$C('$data.Expressions.ToArrayExpression', $data.Expressions.FrameOperator, null, { - constructor: function (source) { - /// - /// - /// - this.source = source; - this.resultType = $data.Array; - }, - nodeType: { value: $data.Expressions.ExpressionType.ToArray, enumerable: true } -}); - -$C('$data.Expressions.SomeExpression', $data.Expressions.FrameOperator, null, { - constructor: function (source) { - /// - /// - /// - this.source = source; - this.resultType = $data.Object; - }, - nodeType: { value: $data.Expressions.ExpressionType.Some, enumerable: true } -}); - -$C('$data.Expressions.EveryExpression', $data.Expressions.FrameOperator, null, { - constructor: function (source) { - /// - /// - /// - this.source = source; - this.resultType = $data.Object; - }, - nodeType: { value: $data.Expressions.ExpressionType.Every, enumerable: true } -}); - -$C('$data.Expressions.BatchDeleteExpression', $data.Expressions.FrameOperator, null, { - constructor: function (source) { - /// - /// - /// - this.source = source; - this.resultType = $data.Integer; - }, - nodeType: { value: $data.Expressions.ExpressionType.BatchDelete, enumerable: true } -});$C('$data.Expressions.IncludeExpression', $data.Expressions.EntitySetExpression, null, { - constructor: function (source, selector) { - }, - nodeType: { value: $data.Expressions.ExpressionType.Include, writable: true }, - - toString: function (debug) { - //var result; - //result = debug ? this.type + " " : ""; - //result = result + this.name; - var result = "unimplemented"; - return result; - } -}, null); -$C('$data.Expressions.MemberInfoExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (memberDefinition) { - this.memberDefinition = memberDefinition; - this.memberName = memberDefinition.name; - }, - nodeType: { value: $data.Expressions.ExpressionType.MemberInfo, enumerable: true } - -});$C('$data.Expressions.OrderExpression', $data.Expressions.EntitySetExpression, null, { - constructor: function (source, expression, nType) { - /// - /// - //this.source = source; - //this.selector = expression; - this.nodeType = nType; - }, - nodeType: { value: $data.Expressions.ExpressionType.OrderBy, writable: true }, - - toString: function (debug) { - //var result; - //result = debug ? this.type + " " : ""; - //result = result + this.name; - var result = "unimplemented"; - return result; - } -}, null); -$C('$data.Expressions.ParametricQueryExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (expression, parameters) { - this.expression = expression; - this.parameters = parameters || []; - }, - nodeType: { value: $data.Expressions.ExpressionType.ParametricQuery, enumerable: true } -});$C('$data.Expressions.ProjectionExpression', $data.Expressions.EntitySetExpression, null, { - constructor: function (source, selector, params, instance) { - - }, - nodeType: { value: $data.Expressions.ExpressionType.Projection, enumerable: true } - -}); - - -$C('$data.Expressions.QueryExpressionCreator', $data.Expressions.EntityExpressionVisitor, null, { - constructor: function (scopeContext) { - /// - Guard.requireValue("scopeContext", scopeContext); - this.scopeContext = scopeContext; - }, - VisitEntitySetExpression: function (expression, context) { - if (expression.source instanceof $data.Expressions.EntityContextExpression) { - this.lambdaTypes.push(expression); - } - return expression; - }, - - VisitServiceOperationExpression: function (expression, context) { - if (expression.source instanceof $data.Expressions.EntityContextExpression) { - this.lambdaTypes.push(expression); - } - return expression; - }, - - VisitCodeExpression: function (expression, context) { - ///Converts the CodeExpression into an EntityExpression - /// - var source = expression.source.toString(); - var jsCodeTree = Container.createCodeParser(this.scopeContext).createExpression(source); - this.scopeContext.log({ event: "JSCodeExpression", data: jsCodeTree }); - - //TODO rename classes to reflex variable names - //TODO engage localValueResolver here - //var globalVariableResolver = Container.createGlobalContextProcessor(window); - var constantResolver = Container.createConstantValueResolver(expression.parameters, window, this.scopeContext); - var parameterProcessor = Container.createParameterResolverVisitor(); - - jsCodeTree = parameterProcessor.Visit(jsCodeTree, constantResolver); - - this.scopeContext.log({ event: "JSCodeExpressionResolved", data: jsCodeTree }); - var code2entity = Container.createCodeToEntityConverter(this.scopeContext); - - ///user provided query parameter object (specified as thisArg earlier) is passed in - var entityExpression = code2entity.Visit(jsCodeTree, { queryParameters: expression.parameters, lambdaParameters: this.lambdaTypes, frameType: context.frameType }); - - ///parameters are referenced, ordered and named, also collected in a flat list of name value pairs - var result = Container.createParametricQueryExpression(entityExpression, code2entity.parameters); - this.scopeContext.log({ event: "EntityExpression", data: entityExpression }); - - return result; - }, - - - VisitFilterExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - context = context || {}; - context.frameType = expression.getType(); - var selector = this.Visit(expression.selector, context); - if (source !== expression.source || selector !== expression.selector) { - return Container.createFilterExpression(source, selector, expression.params, expression.instance); - } - return expression; - }, - - VisitInlineCountExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - context = context || {}; - context.frameType = expression.getType(); - var selector = this.Visit(expression.selector, context); - if (source !== expression.source || selector !== expression.selector) { - return Container.createInlineCountExpression(source, selector, expression.params, expression.instance); - } - return expression; - }, - - VisitProjectionExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - context = context || {}; - context.frameType = expression.getType(); - var selector = this.Visit(expression.selector, context); - if (source !== expression.source || selector !== expression.selector) { - var expr = Container.createProjectionExpression(source, selector, expression.params, expression.instance); - expr.projectionAs = expression.projectionAs; - return expr; - } - return expression; - }, - - VisitOrderExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - context = context || {}; - context.frameType = expression.getType(); - var selector = this.Visit(expression.selector, context); - if (source !== expression.source || selector !== expression.selector) { - return Container.createOrderExpression(source, selector, expression.nodeType); - } - return expression; - } -});$C('$data.Expressions.QueryParameterExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (name, index, value, type) { - this.name = name; - this.index = index; - this.value = value; - //TODO - this.type = Container.getTypeName(value); - }, - - nodeType: { value: $data.Expressions.ExpressionType.QueryParameter, writable: false } -});$C('$data.Expressions.RepresentationExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (kind) { - }, - - getMemberDefinition: function (name) { - return this.entityType.getMemberDefinition(name); - }, - - nodeType: { value: $data.Expressions.ExpressionType.Entity } -}); - -$C('$data.Expressions.ServiceOperationExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (source, selector, params, cfg, boundItem) { - /// - /// - /// - /// - /// - /// - Guard.requireType("source", source, [$data.Expressions.EntityContextExpression]); - Guard.requireType("selector", source, [$data.Expressions.MemberInfoExpression]); - - this.source = source; - this.selector = selector - this.params = params - this.cfg = cfg; - this.boundItem = boundItem; - - function findContext() { - //TODO: use source from function parameter and return a value at the end of the function - var r = source; - while (r) { - if (r instanceof $data.Expressions.EntityContextExpression) { - return r; - } - r = r.source; - } - } - - var c = findContext(); - switch (true) { - case this.source instanceof $data.Expressions.EntityContextExpression: - this.elementType = cfg.elementType ? Container.resolveType(cfg.elementType) : (this.elementType ? Container.resolveType(cfg.returnType) : null); - this.storageModel = cfg.elementType ? c.instance._storageModel.getStorageModel(Container.resolveType(cfg.elementType)) : null; - break; - default: - Guard.raise("Unknown source type for EntitySetExpression: " + this.source.getType().name); - } - - }, - nodeType: { value: $data.Expressions.ExpressionType.ServiceOperation, enumerable: true } -});$C('$data.Expressions.ContinuationExpressionBuilder', $data.Expressions.EntityExpressionVisitor, null, { - constructor: function (mode) { - this.mode = mode; - }, - compile: function (query) { - - var findContext = { mode: "find", skipExists: false }; - this.Visit(query.expression, findContext); - - var result = { - skip: findContext.skipSize, - take: findContext.pageSize, - message: '' - } - - - if ('pageSize' in findContext) { - var expression; - var context = { mode: this.mode, pageSize: findContext.pageSize }; - - if (!findContext.skipExists && (findContext.pageSize)) { - context.append = true; - expression = this.Visit(query.expression, context); - - } else if (findContext.skipExists) { - expression = this.Visit(query.expression, context) - } - - if (!context.abort) { - result.expression = expression - } - else { - result.skip = (result.skip || 0) - result.take; - result.message = 'Invalid skip value!'; - } - }else{ - result.message = 'take expression not defined in the chain!'; - } - - return result; - }, - VisitPagingExpression: function (expression, context) { - - switch (context.mode) { - case 'find': - if (expression.nodeType === $data.Expressions.ExpressionType.Take) { - context.pageSize = expression.amount.value; - } else { - context.skipSize = expression.amount.value; - context.skipExists = true; - } - break; - case 'prev': - if (expression.nodeType === $data.Expressions.ExpressionType.Skip) { - var amount = expression.amount.value - context.pageSize; - context.abort = amount < 0 && expression.amount.value >= context.pageSize; - - var constExp = Container.createConstantExpression(Math.max(amount, 0), "number"); - return Container.createPagingExpression(expression.source, constExp, expression.nodeType); - } else if (context.append) { - //no skip expression, skip: 0, no prev - context.abort = true; - } - break; - case 'next': - if (expression.nodeType === $data.Expressions.ExpressionType.Skip) { - var amount = context.pageSize + expression.amount.value; - var constExp = Container.createConstantExpression(amount, "number"); - return Container.createPagingExpression(expression.source, constExp, expression.nodeType); - } else if (context.append) { - //no skip expression, skip: 0 - var constExp = Container.createConstantExpression(context.pageSize, "number"); - return Container.createPagingExpression(expression, constExp, $data.Expressions.ExpressionType.Skip); - } - break; - default: - } - - this.Visit(expression.source, context); - } -}); -$data.Class.define('$data.Validation.ValidationError', null, null, { - constructor: function (message, propertyDefinition, type) { - /// - /// - - this.Message = message; - this.PropertyDefinition = propertyDefinition; - this.Type = type; - }, - Type: { dataType: 'string' }, - Message: { dataType: "string" }, - PropertyDefinition: { dataType: $data.MemberDefinition } -}, null); - -$data.Class.define('$data.Validation.EntityValidationBase', null, null, { - - ValidateEntity: function (entity) { - /// - return []; - }, - - ValidateEntityField: function (entity, memberDefinition) { - /// - /// - return []; - }, - - getValidationValue: function (memberDefinition, validationName) { - Guard.raise("Pure class"); - }, - getValidationMessage: function (memberDefinition, validationName, defaultMessage) { - Guard.raise("Pure class"); - } - -}, null); - -$data.Validation = $data.Validation || {}; -$data.Validation.Entity = new $data.Validation.EntityValidationBase(); -$data.Class.define('$data.Validation.Defaults', null, null, null, { - validators: { - value: { - required: function (value, definedValue) { return !Object.isNullOrUndefined(value); }, - customValidator: function (value, definedValue) { return Object.isNullOrUndefined(value) || typeof definedValue == "function" ? definedValue(value) : true; }, - - minValue: function (value, definedValue) { return Object.isNullOrUndefined(value) || value >= definedValue; }, - maxValue: function (value, definedValue) { return Object.isNullOrUndefined(value) || value <= definedValue; }, - - minLength: function (value, definedValue) { return Object.isNullOrUndefined(value) || value.length >= definedValue; }, - maxLength: function (value, definedValue) { return Object.isNullOrUndefined(value) || value.length <= definedValue; }, - length: function (value, definedValue) { return Object.isNullOrUndefined(value) || value.length == definedValue; }, - regex: function (value, definedValue) { - return Object.isNullOrUndefined(value) || - value.match(typeof definedValue === 'string' - ? new RegExp((definedValue.indexOf('/') === 0 && definedValue.lastIndexOf('/') === (definedValue.length - 1)) ? definedValue.slice(1, -1) : definedValue) - : definedValue) - } - } - }, - - _getGroupValidations: function (validations) { - var validators = {}; - if (Array.isArray(validations)) { - for (var i = 0; i < validations.length; i++) { - var validator = validations[i]; - if (typeof this.validators[validator] === 'function') { - validators[validator] = this.validators[validator]; - } - } - } - - return validators; - } -}); - -$data.Class.define('$data.Validation.EntityValidation', $data.Validation.EntityValidationBase, null, { - - ValidateEntity: function (entity) { - /// - - var errors = []; - entity.getType().memberDefinitions.getPublicMappedProperties().forEach(function (memDef) { - errors = errors.concat(this.ValidateEntityField(entity, memDef, undefined, true)); - }, this); - return errors; - }, - ValidateEntityField: function (entity, memberDefinition, newValue, valueNotSet) { - /// - /// - var errors = []; - var resolvedType = Container.resolveType(memberDefinition.dataType); - var typeName = Container.resolveName(resolvedType); - var value = !valueNotSet ? newValue : entity[memberDefinition.name]; - - if (!memberDefinition.inverseProperty && resolvedType && typeof resolvedType.isAssignableTo === 'function' && resolvedType.isAssignableTo($data.Entity)) { - typeName = $data.Entity.fullName; - } - - this.fieldValidate(entity, memberDefinition, value, errors, typeName); - return errors; - }, - - getValidationValue: function (memberDefinition, validationName) { - var value; - if (memberDefinition[validationName] && memberDefinition[validationName].value) - value = memberDefinition[validationName].value; - else - value = memberDefinition[validationName]; - - if (this.convertableValidation[validationName]) { - var typeToConvert; - if (this.convertableValidation[validationName] === true) { - typeToConvert = memberDefinition.type; - } else { - typeToConvert = this.convertableValidation[validationName]; - } - - if (typeToConvert) - value = Container.convertTo(value, typeToConvert, memberDefinition.elementType); - } - - return value; - }, - getValidationMessage: function (memberDefinition, validationName, defaultMessage) { - var eMessage = defaultMessage; - if (typeof memberDefinition[validationName] == "object" && memberDefinition[validationName].message) - eMessage = memberDefinition[validationName].message; - else if (memberDefinition.errorMessage) - eMessage = memberDefinition.errorMessage; - - return eMessage; - }, - createValidationError: function (memberDefinition, validationName, defaultMessage) { - return new $data.Validation.ValidationError(this.getValidationMessage(memberDefinition, validationName, defaultMessage), memberDefinition, validationName); - }, - - convertableValidation: { - value: { - required: '$data.Boolean', - minValue: true, - maxValue: true, - minLength: '$data.Integer', - maxLength: '$data.Integer', - length: '$data.Integer' - } - - }, - supportedValidations: { - value: { - //'$data.Entity': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.ObjectID': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.Byte': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minValue', 'maxValue']), - '$data.SByte': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minValue', 'maxValue']), - '$data.Decimal': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minValue', 'maxValue']), - '$data.Float': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minValue', 'maxValue']), - '$data.Number': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minValue', 'maxValue']), - '$data.Int16': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minValue', 'maxValue']), - '$data.Integer': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minValue', 'maxValue']), - '$data.Int32': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minValue', 'maxValue']), - '$data.Int64': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minValue', 'maxValue']), - '$data.String': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minLength', 'maxLength', 'length', 'regex']), - '$data.Date': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minValue', 'maxValue']), - '$data.DateTimeOffset': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minValue', 'maxValue']), - '$data.Time': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minValue', 'maxValue']), - '$data.Boolean': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.Array': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'length']), - '$data.Object': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.Guid': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.Blob': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minLength', 'maxLength', 'length']), - '$data.GeographyPoint': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeographyLineString': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeographyPolygon': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeographyMultiPoint': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeographyMultiLineString': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeographyMultiPolygon': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeographyCollection': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeometryPoint': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeometryLineString': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeometryPolygon': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeometryMultiPoint': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeometryMultiLineString': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeometryMultiPolygon': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeometryCollection': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']) - } - }, - - fieldValidate: function (entity, memberDefinition, value, errors, validationTypeName) { - /// - /// - /// - /// - if (entity.entityState == $data.EntityState.Modified && entity.changedProperties && entity.changedProperties.indexOf(memberDefinition) < 0) - return; - - var validatonGroup = this.supportedValidations[validationTypeName]; - if (validatonGroup) { - var validations = Object.keys(validatonGroup); - validations.forEach(function (validation) { - if (memberDefinition[validation] && validatonGroup[validation] && !validatonGroup[validation].call(entity, value, this.getValidationValue(memberDefinition, validation))) - errors.push(this.createValidationError(memberDefinition, validation, 'Validation error!')); - }, this); - - if (validationTypeName === $data.Entity.fullName && value instanceof $data.Entity && !value.isValid()) { - errors.push(this.createValidationError(memberDefinition, 'ComplexProperty', 'Validation error!')); - } - } - } - -}, null); - -$data.Validation.Entity = new $data.Validation.EntityValidation(); - -$data.Class.define('$data.Notifications.ChangeDistributorBase', null, null, { - distributeData: function (collectorData) { - Guard.raise("Pure class"); - } -}, null); -$data.Class.define('$data.Notifications.ChangeCollectorBase', null, null, { - buildData: function (entityContextData) { - Guard.raise("Pure class"); - }, - processChangedData: function (entityData) { - if (this.Distrbutor && this.Distrbutor.distributeData) - this.Distrbutor.distributeData(this.buildData(entityData)); - }, - Distrbutor: { enumerable: false, dataType: $data.Notifications.ChangeDistributorBase, storeOnObject: true } -}, null); -$data.Class.define('$data.Notifications.ChangeDistributor', $data.Notifications.ChangeDistributorBase, null, { - constructor: function (broadcastUrl) { - this.broadcastUrl = broadcastUrl; - }, - distributeData: function (data) { - $data.ajax({ - url: this.broadcastUrl, - type: "POST", - data: 'data=' + JSON.stringify(data), - succes: this.success, - error: this.error - }); - }, - broadcastUrl: { dataType: "string" }, - success: function () { }, - error: function () { } -}, null); -$data.Class.define('$data.Notifications.ChangeCollector', $data.Notifications.ChangeCollectorBase, null, { - buildData: function (entities) { - var result = []; - entities.forEach(function (element) { - var resObj = { entityState: element.data.entityState, typeName: element.data.getType().name }; - var enumerableMemDefCollection = []; - - switch (element.data.entityState) { - case $data.EntityState.Added: - enumerableMemDefCollection = element.data.getType().memberDefinitions.getPublicMappedProperties(); - break; - case $data.EntityState.Modified: - enumerableMemDefCollection = element.data.changedProperties; - break; - case $data.EntityState.Deleted: - enumerableMemDefCollection = element.data.getType().memberDefinitions.getKeyProperties(); - break; - default: - break; - } - - enumerableMemDefCollection.forEach(function (memDef) { - resObj[memDef.name] = element.data[memDef.name]; - }); - - result.push(resObj); - }); - - return result; - } -}, null);$data.Class.define('$data.Transaction', null, null, { - constructor: function () { - this._objectId = (new Date()).getTime(); - $data.Trace.log("create: ", this._objectId); - - this.oncomplete = new $data.Event("oncomplete", this); - this.onerror = new $data.Event("onerror", this); - }, - abort: function () { - Guard.raise(new Exception('Not Implemented', 'Not Implemented', arguments)); - }, - - _objectId: { type: $data.Integer }, - transaction: { type: $data.Object }, - - oncomplete: { type: $data.Event }, - onerror: { type: $data.Event } -}, null);$data.Class.define('$data.Access', null, null, {}, { - isAuthorized: function(access, user, sets, callback){ - var pHandler = new $data.PromiseHandler(); - var clbWrapper = pHandler.createCallback(callback); - var pHandlerResult = pHandler.getPromise(); - - //clbWrapper.error('Authorization failed', 'Access authorization'); - clbWrapper.success(true); - - return pHandlerResult; - - /*var error; - - if (!access) error = 'Access undefined'; - if (typeof access !== 'number') error = 'Invalid access type'; - if (!user) user = {}; //error = 'User undefined'; - if (!user.roles) user.roles = {}; //error = 'User has no roles'; - if (!roles) roles = {}; //error = 'Roles undefined'; - if (!(roles instanceof Array || typeof roles === 'object')) error = 'Invald roles type'; - - var pHandler = new $data.PromiseHandler(); - var clbWrapper = pHandler.createCallback(callback); - var pHandlerResult = pHandler.getPromise(); - - if (error){ - clbWrapper.error(error, 'Access authorization'); - return pHandlerResult; - } - - if (user.roles instanceof Array){ - var r = {}; - for (var i = 0; i < user.roles.length; i++){ - if (typeof user.roles[i] === 'string') r[user.roles[i]] = true; - } - user.roles = r; - } - - if (roles instanceof Array){ - var r = {}; - for (var i = 0; i < roles.length; i++){ - if (typeof roles[i] === 'string') r[roles[i]] = true; - } - roles = r; - } - - var args = arguments; - var readyFn = function(result){ - if (result) clbWrapper.success(result); - else clbWrapper.error('Authorization failed', args); - }; - - var rolesKeys = Object.getOwnPropertyNames(roles); - var i = 0; - - var callbackFn = function(result){ - if (result) readyFn(result); - - if (typeof roles[rolesKeys[i]] === 'boolean' && roles[rolesKeys[i]]){ - if (user.roles[rolesKeys[i]]) readyFn(true); - else{ - i++; - if (i < rolesKeys.length) callbackFn(); - else readyFn(false); - } - }else if (typeof roles[rolesKeys[i]] === 'function'){ - var r = roles[rolesKeys[i]].call(user); - - if (typeof r === 'function') r.call(user, (i < rolesKeys.length ? callbackFn : readyFn)); - else{ - if (r) readyFn(true); - else{ - i++; - if (i < rolesKeys.length) callbackFn(); - else readyFn(false); - } - } - }else if (typeof roles[rolesKeys[i]] === 'number'){ - if (((typeof user.roles[rolesKeys[i]] === 'number' && (user.roles[rolesKeys[i]] & access)) || - (typeof user.roles[rolesKeys[i]] !== 'number' && user.roles[rolesKeys[i]])) && - (roles[rolesKeys[i]] & access)) user.roles[rolesKeys[i]] && readyFn(true); - else{ - i++; - if (i < rolesKeys.length) callbackFn(); - else readyFn(false); - } - } - }; - - callbackFn(); - - return pHandlerResult;*/ - }, - getAccessBitmaskFromPermission: function(p){ - var access = $data.Access.None; - - if (p.Create) access |= $data.Access.Create; - if (p.Read) access |= $data.Access.Read; - if (p.Update) access |= $data.Access.Update; - if (p.Delete) access |= $data.Access.Delete; - if (p.DeleteBatch) access |= $data.Access.DeleteBatch; - if (p.Execute) access |= $data.Access.Execute; - - return access; - }, - None: { value: 0 }, - Create: { value: 1 }, - Read: { value: 2 }, - Update: { value: 4 }, - Delete: { value: 8 }, - DeleteBatch: { value: 16 }, - Execute: { value: 32 } -}); -$data.Class.define('$data.Promise', null, null, { - always: function () { Guard.raise(new Exception('$data.Promise.always', 'Not implemented!')); }, - done: function () { Guard.raise(new Exception('$data.Promise.done', 'Not implemented!')); }, - fail: function () { Guard.raise(new Exception('$data.Promise.fail', 'Not implemented!')); }, - isRejected: function () { Guard.raise(new Exception('$data.Promise.isRejected', 'Not implemented!')); }, - isResolved: function () { Guard.raise(new Exception('$data.Promise.isResolved', 'Not implemented!')); }, - //notify: function () { Guard.raise(new Exception('$data.Promise.notify', 'Not implemented!')); }, - //notifyWith: function () { Guard.raise(new Exception('$data.Promise.notifyWith', 'Not implemented!')); }, - pipe: function () { Guard.raise(new Exception('$data.Promise.pipe', 'Not implemented!')); }, - progress: function () { Guard.raise(new Exception('$data.Promise.progress', 'Not implemented!')); }, - promise: function () { Guard.raise(new Exception('$data.Promise.promise', 'Not implemented!')); }, - //reject: function () { Guard.raise(new Exception('$data.Promise.reject', 'Not implemented!')); }, - //rejectWith: function () { Guard.raise(new Exception('$data.Promise.rejectWith', 'Not implemented!')); }, - //resolve: function () { Guard.raise(new Exception('$data.Promise.resolve', 'Not implemented!')); }, - //resolveWith: function () { Guard.raise(new Exception('$data.Promise.resolveWith', 'Not implemented!')); }, - state: function () { Guard.raise(new Exception('$data.Promise.state', 'Not implemented!')); }, - then: function () { Guard.raise(new Exception('$data.Promise.then', 'Not implemented!')); } -}, null); - -$data.Class.define('$data.PromiseHandlerBase', null, null, { - constructor: function () { }, - createCallback: function (callBack) { - callBack = $data.typeSystem.createCallbackSetting(callBack); - - return cbWrapper = { - success: callBack.success, - error: callBack.error, - notify: callBack.notify - }; - }, - getPromise: function () { - return new $data.Promise(); - } -}, null); - -$data.PromiseHandler = $data.PromiseHandlerBase; -var EventSubscriber = $data.Class.define("EventSubscriber", null, null, { - constructor: function (handler, state, thisArg) { - /// - /// event handler - /// - /// - /// - /// - /// - /// - /// custom state object - /// [i]this[/i] context for handler - /// - /// event handler - /// custom state object - /// [i]this[/i] context for handler - this.handler = handler; - this.state = state; - this.thisArg = thisArg; - }, - handler: {}, - state: {}, - thisArg: {} -}); - -$data.Event = Event = $data.Class.define("$data.Event", null, null, { - constructor: function (name, sender) { - ///The name of the event - ///The originator/sender of the event. [this] in handlers will be set to this - var subscriberList = null; - var parentObject = sender; - - function detachHandler(list, handler) { - /// - /// - list.forEach(function (item, index) { - if (item.handler == handler) { - list.splice(index, 1); - } - }); - } - - this.attach = function (handler, state, thisArg) { - /// - /// - /// - /// - /// - /// - /// - /// - /// - if (!subscriberList) { - subscriberList = []; - } - subscriberList.push(new EventSubscriber(handler, state, thisArg || sender)); - }; - this.detach = function (handler) { - detachHandler(subscriberList, handler); - }; - this.fire = function (eventData, snder) { - var snd = snder || sender || this; - //eventData.eventName = name; - /// - if (subscriberList) { - subscriberList.forEach(function (subscriber) { - /// - try { - subscriber.handler.call(subscriber.thisArg, snd, eventData, subscriber.state); - } catch(ex) { - console.log("unhandled exception in event handler. exception suppressed"); - console.dir(ex); - } - }); - } - }; - this.fireCancelAble = function (eventData, snder) { - var snd = snder || sender || this; - //eventData.eventName = name; - /// - var isValid = true; - if (subscriberList) { - subscriberList.forEach(function (subscriber) { - /// - try { - isValid = isValid && (subscriber.handler.call(subscriber.thisArg, snd, eventData, subscriber.state) === false ? false : true); - } catch (ex) { - console.log("unhandled exception in event handler. exception suppressed"); - console.dir(ex); - } - }); - } - return isValid; - }; - } -}); - - -var eventData = $data.Class.define("EventData", null, null, { - eventName: {} -}); - -var PropertyChangeEventData = $data.Class.define("PropertyChangeEventData", EventData, null, { - constructor: function (propertyName, oldValue, newValue) { - this.propertyName = propertyName; - this.oldValue = oldValue; - this.newValue = newValue; - }, - propertyName: {}, - oldValue: {}, - newValue: {} -}); - -var PropertyValidationEventData = $data.Class.define("PropertyValidationEventData", EventData, null, { - constructor: function (propertyName, oldValue, newValue, errors) { - this.propertyName = propertyName; - this.oldValue = oldValue; - this.newValue = newValue; - this.errors = errors; - this.cancel = false; - }, - propertyName: {}, - oldValue: {}, - newValue: {}, - errors: {}, - cancel: {} -}); - - - -$data.Entity = Entity = $data.Class.define("$data.Entity", null, null, { - constructor: function (initData, newInstanceOptions) { - /// - /// This class provide a light weight, object-relational interface between - /// your javascript code and database. - /// - /// - /// - /// initialization data - /// - /// var category = new $news.Types.Category({ Title: 'Tech' }); - /// $news.context.Categories.add(category); - /// - /// - /// - /// initialization data - /// - /// - /// - /// - /// Determines the current $data.Entity is validated. - /// array of $data.Validation.ValidationError - /// array of MemberDefinition - /// - /// array of MemberDefinition - - this.initData = {}; - var thisType = this.getType(); - if (thisType.__copyPropertiesToInstance) { - $data.typeSystem.writePropertyValues(this); - } - - var ctx = null; - this.context = ctx; - if ("setDefaultValues" in thisType) { - if (!newInstanceOptions || newInstanceOptions.setDefaultValues !== false) { - if (!initData || Object.keys(initData).length < 1) { - initData = thisType.setDefaultValues(initData); - } - } - } - - if (typeof initData === "object") { - var typeMemDefs = thisType.memberDefinitions; - var memDefNames = typeMemDefs.getPublicMappedPropertyNames(); - - for (var i in initData) { - if (memDefNames.indexOf(i) > -1) { - var memberDef = typeMemDefs.getMember(i); - var type = Container.resolveType(memberDef.type); - var value = initData[i]; - - if (memberDef.concurrencyMode === $data.ConcurrencyMode.Fixed) { - this.initData[i] = value; - } else { - if (newInstanceOptions && newInstanceOptions.converters) { - var converter = newInstanceOptions.converters[Container.resolveName(type)]; - if (converter) - value = converter(value); - } - - this.initData[i] = Container.convertTo(value, type, memberDef.elementType, newInstanceOptions); - } - } - } - - } - - if (newInstanceOptions && newInstanceOptions.entityBuilder) { - newInstanceOptions.entityBuilder(this, thisType.memberDefinitions.asArray(), thisType); - } - - this.changedProperties = undefined; - this.entityState = undefined; - - }, - toString: function () { - /// Returns a string that represents the current $data.Entity - /// - - return this.getType().fullName + "(" + (this.Id || this.Name || '') + ")" - }, - toJSON: function () { - /// Creates pure JSON object from $data.Entity. - /// JSON representation - - var result = {}; - var self = this; - this.getType().memberDefinitions.getPublicMappedProperties().forEach(function (memDef) { - if (self[memDef.name] instanceof Date && memDef.type && Container.resolveType(memDef.type) === $data.DateTimeOffset) { - result[memDef.name] = new $data.DateTimeOffset(self[memDef.name]); - } else { - result[memDef.name] = self[memDef.name]; - } - }); - return result; - }, - equals: function (entity) { - /// Determines whether the specified $data.Entity is equal to the current $data.Entity. - /// [b]true[/b] if the specified $data.Entity is equal to the current $data.Entity; otherwise, [b]false[/b]. - - if (entity.getType() !== this.getType()) { - return false; - } - var entityPk = this.getType().memberDefinitions.getKeyProperties(); - for (var i = 0; i < entityPk.length; i++) { - if (this[entityPk[i].name] != entity[entityPk[i].name]) { - return false; - } - } - return true; - }, - - propertyChanging: { - dataType: $data.Event, storeOnObject: true, monitorChanges: false, notMapped: true, enumerable: false, prototypeProperty: true, - get: function () { - if (!this._propertyChanging) - this._propertyChanging = new Event('propertyChanging', this); - - return this._propertyChanging; - }, - set: function (value) { this._propertyChanging = value; } - }, - - propertyChanged: { - dataType: $data.Event, storeOnObject: true, monitorChanges: false, notMapped: true, enumerable: false, prototypeProperty: true, - get: function () { - if (!this._propertyChanged) - this._propertyChanged = new Event('propertyChanged', this); - - return this._propertyChanged; - }, - set: function (value) { this._propertyChanged = value; } - }, - - propertyValidationError: { - dataType: $data.Event, storeOnObject: true, monitorChanges: false, notMapped: true, enumerable: false, prototypeProperty: true, - get: function () { - if (!this._propertyValidationError) - this._propertyValidationError = new Event('propertyValidationError', this); - - return this._propertyValidationError; - }, - set: function (value) { this._propertyValidationError = value; } - }, - - // protected - storeProperty: function (memberDefinition, value) { - /// - /// - - if (memberDefinition.concurrencyMode !== $data.ConcurrencyMode.Fixed) { - value = Container.convertTo(value, memberDefinition.type, memberDefinition.elementType); - } - - var eventData = null; - if (memberDefinition.monitorChanges != false && (this._propertyChanging || this._propertyChanged || "instancePropertyChanged" in this.constructor)) { - var origValue = this[memberDefinition.name]; - eventData = new PropertyChangeEventData(memberDefinition.name, origValue, value); - if (this._propertyChanging) - this.propertyChanging.fire(eventData); - } - - if (memberDefinition.monitorChanges != false && (this._propertyValidationError || "instancePropertyValidationError" in this.constructor)) { - var errors = $data.Validation.Entity.ValidateEntityField(this, memberDefinition, value); - if (errors.length > 0) { - var origValue = this[memberDefinition.name]; - var errorEventData = new PropertyValidationEventData(memberDefinition.name, origValue, value, errors); - - if (this._propertyValidationError) - this.propertyValidationError.fire(errorEventData); - if ("instancePropertyValidationError" in this.constructor) - this.constructor["instancePropertyValidationError"].fire(errorEventData, this); - - if (errorEventData.cancel == true) - return; - } - } - - if (memberDefinition.storeOnObject == true) { - //TODO refactor to Base.getBackingFieldName - var backingFieldName = "_" + memberDefinition.name; - this[backingFieldName] = value; - } else { - this.initData[memberDefinition.name] = value; - } - this.isValidated = false; - - if (memberDefinition.monitorChanges != false && this.entityState == $data.EntityState.Unchanged) - this.entityState = $data.EntityState.Modified; - - this._setPropertyChanged(memberDefinition); - - if (memberDefinition.monitorChanges != false) { - //if (!this.changedProperties) { - // this.changedProperties = []; - //} - - //if (!this.changedProperties.some(function (memDef) { return memDef.name == memberDefinition.name })) - // this.changedProperties.push(memberDefinition); - - if (this._propertyChanged) - this.propertyChanged.fire(eventData); - - //TODO mixin framework - if ("instancePropertyChanged" in this.constructor) { - this.constructor["instancePropertyChanged"].fire(eventData, this); - } - } - }, - _setPropertyChanged: function (memberDefinition) { - if (memberDefinition.monitorChanges != false) { - if (!this.changedProperties) { - this.changedProperties = []; - } - - if (!this.changedProperties.some(function (memDef) { return memDef.name == memberDefinition.name })) - this.changedProperties.push(memberDefinition); - } - }, - - // protected - retrieveProperty: function (memberDefinition) { - /// - - if (memberDefinition.storeOnObject == true) { - //TODO refactor to Base.getBackingFieldName - var backingFieldName = "_" + memberDefinition.name; - return this[backingFieldName]; - } else { - return this.initData[memberDefinition.name]; - } - }, - - // protected - getProperty: function (memberDefinition, callback, tran) { - /// Retrieve value of member - /// - /// - /// - /// - /// - /// - /// value associated for [i]memberDefinition[/i] - - callback = $data.typeSystem.createCallbackSetting(callback); - if (this[memberDefinition.name] != undefined) { - if (tran instanceof $data.Transaction) - callback.success(this[memberDefinition.name], tran); - else - callback.success(this[memberDefinition.name]); - return; - } - - var context = this.context; - if (!this.context) { - try { - var that = this; - var storeToken = this.storeToken || this.getType().storeToken; - if (storeToken && typeof storeToken.factory === 'function') { - var ctx = storeToken.factory(); - return ctx.onReady().then(function (context) { - return context.loadItemProperty(that, memberDefinition, callback); - }); - } - } catch (e) { } - - Guard.raise(new Exception('Entity not in context', 'Invalid operation')); - } else { - return context.loadItemProperty(this, memberDefinition, callback, tran); - } - }, - // protected - setProperty: function (memberDefinition, value, callback, tran) { - /// - /// - /// done - this[memberDefinition.name] = value; - - //callback = $data.typeSystem.createCallbackSetting(callback); - var pHandler = new $data.PromiseHandler(); - callback = pHandler.createCallback(callback); - callback.success(this[memberDefinition.name]); - return pHandler.getPromise(); - }, - - isValid: function () { - /// Determines the current $data.Entity is validated and valid. - /// - - if (!this.isValidated) { - this.ValidationErrors = $data.Validation.Entity.ValidateEntity(this); - this.isValidated = true; - } - return this.ValidationErrors.length == 0; - }, - isValidated: { dataType: "bool", storeOnObject: true, monitorChanges: false, notMapped: true, enumerable: false, value: false }, - ValidationErrors: { - dataType: Array, - elementType: $data.Validation.ValidationError, - storeOnObject: true, - monitorChanges: true, - notMapped: true, - enumerable: false - }, - - resetChanges: function () { - /// reset changes - - delete this._changedProperties; - }, - - changedProperties: { - dataType: Array, - elementType: window["MemberDefinition"], - storeOnObject: true, - monitorChanges: false, - notMapped: true, - enumerable: false - }, - - entityState: { dataType: "integer", storeOnObject: true, monitorChanges: false, notMapped: true, enumerable: false }, - /* - toJSON: function () { - if (this.context) { - var itemType = this.getType(); - var storageModel = this.context._storageModel[itemType.name]; - var o = new Object(); - for (var property in this) { - if (typeof this[property] !== "function") { - var excludedFields = storageModel.Associations.every(function (association) { - return association.FromPropertyName == property && (association.FromMultiplicity == "0..1" || association.FromMultiplicity == "1"); - }, this); - if (!excludedFields) { - o[property] = this[property]; - } - } - } - return o; - } - return this; - } */ - //, - - //onReady: function (callback) { - // this.__onReadyList = this.__onReadyList || []; - // this.__onReadyList.push(callback); - //}, - - remove: function () { - if ($data.ItemStore && 'EntityInstanceRemove' in $data.ItemStore) - return $data.ItemStore.EntityInstanceRemove.apply(this, arguments); - else - throw 'not implemented'; //todo - }, - save: function () { - if ($data.ItemStore && 'EntityInstanceSave' in $data.ItemStore) - return $data.ItemStore.EntityInstanceSave.apply(this, arguments); - else - throw 'not implemented'; //todo - }, - refresh: function () { - if ($data.ItemStore && 'EntityInstanceSave' in $data.ItemStore) - return $data.ItemStore.EntityInstanceRefresh.apply(this, arguments); - else - throw 'not implemented'; //todo - }, - storeToken: { type: Object, monitorChanges: false, notMapped: true, storeOnObject: true }, - - getFieldUrl: function (field) { - if (this.context) { - return this.context.getFieldUrl(this, field); - } else if (this.getType().storeToken && typeof this.getType().storeToken.factory === 'function') { - var context = this.getType().storeToken.factory(); - return context.getFieldUrl(this, field); - } else if (this.getType().storeToken){ - try { - var ctx = $data.ItemStore._getContextPromise('default', this.getType()); - if (ctx instanceof $data.EntityContext) { - return ctx.getFieldUrl(this, field); - } - } catch (e) { - } - } - return '#'; - } -}, -{ - //create get_[property] and set_[property] functions for properties - __setPropertyfunctions: { value: true, notMapped: true, enumerable: false, storeOnObject: true }, - //copy public properties to current instance - __copyPropertiesToInstance: { value: false, notMapped: true, enumerable: false, storeOnObject: true }, - - inheritedTypeProcessor: function (type) { - if ($data.ItemStore && 'EntityInheritedTypeProcessor' in $data.ItemStore) - $data.ItemStore.EntityInheritedTypeProcessor.apply(this, arguments); - - //default value setter method factory - type.defaultValues = {}; - - type.memberDefinitions.asArray().forEach(function (pd) { - if (pd.hasOwnProperty("defaultValue")) { - type.defaultValues[pd.name] = pd.defaultValue; - } - }); - - if (Object.keys(type.defaultValues).length > 0) { - type.setDefaultValues = function (initData, instance) { - initData = initData || {}; - var dv = type.defaultValues; - for (var n in dv) { - if (!(n in initData)) { - var value = dv[n]; - if ("function" === typeof value) { - initData[n] = dv[n](n, instance); - } else { - initData[n] = dv[n]; - } - } - } - return initData; - } - } - }, - - - //Type Events - addEventListener: function(eventName, fn) { - var delegateName = "on" + eventName; - if (!(delegateName in this)) { - this[delegateName] = new $data.Event(eventName, this); - } - this[delegateName].attach(fn); - }, - removeEventListener: function(eventName, fn) { - var delegateName = "on" + eventName; - if (!(delegateName in this)) { - return; - } - this[delegateName].detach(fn); - }, - raiseEvent: function(eventName, data) { - var delegateName = "on" + eventName; - if (!(delegateName in this)) { - return; - } - this[delegateName].fire(data); - }, - - getFieldNames: function () { - return this.memberDefinitions.getPublicMappedPropertyNames(); - }, - - 'from$data.Object': function (value, type, t, options) { - if (!Object.isNullOrUndefined(value)) { - var newInstanceOptions; - if (options && options.converters) { - newInstanceOptions = { - converters: options.converters - } - } - - return new this(value, newInstanceOptions); - } else { - return value; - } - } - -}); - - -$data.define = function (name, container, definition) { - if (container && !(container instanceof $data.ContainerClass)) { - definition = container; - container = undefined; - } - if (!definition) { - throw new Error("json object type is not supported yet"); - } - var _def = {}; - var hasKey = false; - var keyFields = []; - Object.keys(definition).forEach(function (fieldName) { - var propDef = definition[fieldName]; - if (typeof propDef === 'object' && ("type" in propDef || "get" in propDef || "set" in propDef)) { - - _def[fieldName] = propDef; - if (propDef.key) { - keyFields.push(propDef); - } - - if (("get" in propDef || "set" in propDef) && (!('notMapped' in propDef) || propDef.notMapped === true)) { - propDef.notMapped = true; - propDef.storeOnObject = true; - } - if ("get" in propDef && !("set" in propDef)) { - propDef.set = function () { }; - } else if ("set" in propDef && !("get" in propDef)) { - propDef.get = function () { }; - } - - } else { - _def[fieldName] = { type: propDef }; - } - }); - - if (keyFields.length < 1) { - var keyProp; - switch (true) { - case "id" in _def: - keyProp = "id"; - break; - case "Id" in _def: - keyProp = "Id" - break; - case "ID" in _def: - keyProp = "ID" - break; - } - if (keyProp) { - _def[keyProp].key = true; - var propTypeName = $data.Container.resolveName(_def[keyProp].type); - _def[keyProp].computed = true; - //if ("$data.Number" === propTypeName || "$data.Integer" === propTypeName) { - //} - } else { - _def.Id = { type: "int", key: true, computed: true } - } - } - - - var entityType = $data.Entity.extend(name, container, _def); - return entityType; -} -$data.implementation = function (name) { - return Container.resolveType(name); -}; - - - - -(function () { - - $data.defaults = $data.defaults || {}; - $data.defaults.defaultDatabaseName = 'JayDataDefault'; - -})(); - - -$data.Class.define('$data.StorageModel', null, null, { - constructor: function () { - ///User defined type - this.ComplexTypes = []; - this.Associations = []; - }, - LogicalType: {}, - LogicalTypeName: {}, - PhysicalType: {}, - PhysicalTypeName: {}, - EventHandlers: {}, - TableName: {}, - TableOptions: { value: undefined }, - ComplexTypes: {}, - Associations: {}, - ContextType: {}, - Roles: {} -}, null); -$data.Class.define('$data.Association', null, null, { - constructor: function (initParam) { - if (initParam) { - this.From = initParam.From; - this.FromType = initParam.FromType; - this.FromMultiplicity = initParam.FromMultiplicity; - this.FromPropertyName = initParam.FromPropertyName; - this.To = initParam.To; - this.ToType = initParam.ToType; - this.ToMultiplicity = initParam.ToMultiplicity; - this.ToPropertyName = initParam.ToPropertyName; - } - }, - From: {}, - FromType: {}, - FromMultiplicity: {}, - FromPropertyName: {}, - To: {}, - ToType: {}, - ToMultiplicity: {}, - ToPropertyName: {}, - ReferentialConstraint: {} -}, null); -$data.Class.define('$data.ComplexType', $data.Association, null, {}, null); - -$data.Class.define('$data.EntityContext', null, null, -{ - constructor: function (storageProviderCfg) { - /// Provides facilities for querying and working with entity data as objects. - ///Storage provider specific configuration object. - - if ($data.ItemStore && 'ContextRegister' in $data.ItemStore) - $data.ItemStore.ContextRegister.apply(this, arguments); - - if (storageProviderCfg.queryCache) - this.queryCache = storageProviderCfg.queryCache; - - if ("string" === typeof storageProviderCfg) { - if (0 === storageProviderCfg.indexOf("http")) { - storageProviderCfg = { - name: "oData", - oDataServiceHost: storageProviderCfg - } - } else { - storageProviderCfg = { - name: "local", - databaseName: storageProviderCfg - } - } - } - - if ("provider" in storageProviderCfg) { - storageProviderCfg.name = storageProviderCfg.provider; - } - - //Initialize properties - this.lazyLoad = false; - this.trackChanges = false; - this._entitySetReferences = {}; - this._storageModel = []; - - var ctx = this; - ctx._isOK = false; - - var origSuccessInitProvider = this._successInitProvider; - this._successInitProvider = function (errorOrContext) { - if (errorOrContext instanceof $data.EntityContext) { - origSuccessInitProvider(ctx); - } else { - origSuccessInitProvider(ctx, errorOrContext); - } - } - - this._storageModel.getStorageModel = function (typeName) { - var name = Container.resolveName(typeName); - return ctx._storageModel[name]; - }; - if (typeof storageProviderCfg.name === 'string') { - var tmp = storageProviderCfg.name; - storageProviderCfg.name = [tmp]; - } - var i = 0, providerType; - var providerList = [].concat(storageProviderCfg.name); - var callBack = $data.typeSystem.createCallbackSetting({ success: this._successInitProvider, error: this._successInitProvider }); - - this._initStorageModelSync(); - ctx._initializeEntitySets(ctx.getType()); - - $data.StorageProviderLoader.load(providerList, { - success: function (providerType) { - ctx.storageProvider = new providerType(storageProviderCfg, ctx); - ctx.storageProvider.setContext(ctx); - ctx.stateManager = new $data.EntityStateManager(ctx); - - var contextType = ctx.getType(); - if (providerType.name in contextType._storageModelCache) { - ctx._storageModel = contextType._storageModelCache[providerType.name]; - } else { - ctx._initializeStorageModel(); - contextType._storageModelCache[providerType.name] = ctx._storageModel; - } - - //ctx._initializeEntitySets(contextType); - if (storageProviderCfg && storageProviderCfg.user) Object.defineProperty(ctx, 'user', { value: storageProviderCfg.user, enumerable: true }); - if (storageProviderCfg && storageProviderCfg.checkPermission) Object.defineProperty(ctx, 'checkPermission', { value: storageProviderCfg.checkPermission, enumerable: true }); - - //ctx._isOK = false; - ctx._initializeStore(callBack); - }, - error: function () { - callBack.error('Provider fallback failed!'); - } - }); - - - - this.addEventListener = function (eventName, fn) { - var delegateName = "on" + eventName; - if (!(delegateName in this)) { - this[delegateName] = new $data.Event(eventName, this); - } - this[delegateName].attach(fn); - }; - - this.removeEventListener = function (eventName, fn) { - var delegateName = "on" + eventName; - if (!(delegateName in this)) { - return; - } - this[delegateName].detach(fn); - }; - - this.raiseEvent = function (eventName, data) { - var delegateName = "on" + eventName; - if (!(delegateName in this)) { - return; - } - this[delegateName].fire(data); - }; - - - this.ready = this.onReady({ - success: $data.defaultSuccessCallback, - error: function () { - if ($data.PromiseHandler !== $data.PromiseHandlerBase) { - $data.defaultErrorCallback.apply(this, arguments); - } else { - $data.Trace.error(arguments); - } - } - }); - }, - beginTransaction: function () { - var tables = null; - var callBack = null; - var isWrite = false; - - function readParam(value) { - if (Object.isNullOrUndefined(value)) return; - - if (typeof value === 'boolean') { - isWrite = value; - } else if (Array.isArray(value)) { - tables = value; - } else { - callBack = value; - } - } - - readParam(arguments[0]); - readParam(arguments[1]); - readParam(arguments[2]); - - var pHandler = new $data.PromiseHandler(); - callBack = pHandler.createCallback(callBack); - - //callBack = $data.typeSystem.createCallbackSetting(callBack); - this.storageProvider._beginTran(tables, isWrite, callBack); - - return pHandler.getPromise(); - }, - _isReturnTransaction: function (transaction) { - return transaction instanceof $data.Base || transaction === 'returnTransaction'; - }, - _applyTransaction: function (scope, cb, args, transaction, isReturnTransaction) { - if (isReturnTransaction === true) { - if (transaction instanceof $data.Transaction) { - Array.prototype.push.call(args, transaction); - cb.apply(scope, args); - } else { - this.beginTransaction(function (tran) { - Array.prototype.push.call(args, tran); - cb.apply(scope, args); - }); - } - } - else { - cb.apply(scope, args); - } - }, - - getDataType: function (dataType) { - // Obsolate - if (typeof dataType == "string") { - var memDef_dataType = this[dataType]; - if (memDef_dataType === undefined || memDef_dataType === null) { memDef_dataType = eval(dataType); } - return memDef_dataType; - } - return dataType; - }, - _initializeEntitySets: function (ctor) { - - for (var i = 0, l = this._storageModel.length; i < l; i++){ - var storageModel = this._storageModel[i]; - this[storageModel.ItemName] = new $data.EntitySet(storageModel.LogicalType, this, storageModel.ItemName, storageModel.EventHandlers, storageModel.Roles); - var sm = this[storageModel.ItemName]; - sm.name = storageModel.ItemName; - sm.tableName = storageModel.TableName; - sm.tableOptions = storageModel.TableOptions; - sm.eventHandlers = storageModel.EventHandlers; - this._entitySetReferences[storageModel.LogicalType.name] = sm; - - this._initializeActions(sm, ctor, ctor.getMemberDefinition(storageModel.ItemName)); - - } - - }, - _initializeStore: function (callBack) { - if (this.storageProvider) { - this.storageProvider.initializeStore(callBack); - } - }, - - _initStorageModelSync: function() { - var _memDefArray = this.getType().memberDefinitions.asArray(); - - - for (var i = 0; i < _memDefArray.length; i++) { - var item = _memDefArray[i]; - if ('dataType' in item) { - var itemResolvedDataType = Container.resolveType(item.dataType); - if (itemResolvedDataType && itemResolvedDataType.isAssignableTo && itemResolvedDataType.isAssignableTo($data.EntitySet)) { - var elementType = Container.resolveType(item.elementType); - var storageModel = new $data.StorageModel(); - storageModel.TableName = item.tableName || item.name; - storageModel.TableOptions = item.tableOptions; - storageModel.ItemName = item.name; - storageModel.LogicalType = elementType; - storageModel.LogicalTypeName = elementType.name; - storageModel.PhysicalTypeName = $data.EntityContext._convertLogicalTypeNameToPhysical(storageModel.LogicalTypeName); - storageModel.ContextType = this.getType(); - storageModel.Roles = item.roles; - if (item.indices) { - storageModel.indices = item.indices; - } - if (item.beforeCreate) { - if (!storageModel.EventHandlers) storageModel.EventHandlers = {}; - storageModel.EventHandlers.beforeCreate = item.beforeCreate; - } - if (item.beforeRead) { - if (!storageModel.EventHandlers) storageModel.EventHandlers = {}; - storageModel.EventHandlers.beforeRead = item.beforeRead; - } - if (item.beforeUpdate) { - if (!storageModel.EventHandlers) storageModel.EventHandlers = {}; - storageModel.EventHandlers.beforeUpdate = item.beforeUpdate; - } - if (item.beforeDelete) { - if (!storageModel.EventHandlers) storageModel.EventHandlers = {}; - storageModel.EventHandlers.beforeDelete = item.beforeDelete; - } - if (item.afterCreate) { - if (!storageModel.EventHandlers) storageModel.EventHandlers = {}; - storageModel.EventHandlers.afterCreate = item.afterCreate; - } - if (item.afterRead) { - if (!storageModel.EventHandlers) storageModel.EventHandlers = {}; - storageModel.EventHandlers.afterRead = item.afterRead; - } - if (item.afterUpdate) { - if (!storageModel.EventHandlers) storageModel.EventHandlers = {}; - storageModel.EventHandlers.afterUpdate = item.afterUpdate; - } - if (item.afterDelete) { - if (!storageModel.EventHandlers) storageModel.EventHandlers = {}; - storageModel.EventHandlers.afterDelete = item.afterDelete; - } - this._storageModel.push(storageModel); - var name = Container.resolveName(elementType); - this._storageModel[name] = storageModel; - } - } - } - - }, - _initializeStorageModel: function () { - - - var _memDefArray = this.getType().memberDefinitions.asArray(); - - - if (typeof intellisense !== 'undefined') - return; - - - for (var i = 0; i < this._storageModel.length; i++) { - var storageModel = this._storageModel[i]; - - ///Storage model item - var dbEntityInstanceDefinition = {}; - - storageModel.Associations = storageModel.Associations || []; - storageModel.ComplexTypes = storageModel.ComplexTypes || []; - for (var j = 0; j < storageModel.LogicalType.memberDefinitions.getPublicMappedProperties().length; j++) { - var memDef = storageModel.LogicalType.memberDefinitions.getPublicMappedProperties()[j]; - ///Member definition instance - - var memDefResolvedDataType = Container.resolveType(memDef.dataType); - - if ((this.storageProvider.supportedDataTypes.indexOf(memDefResolvedDataType) > -1) && Object.isNullOrUndefined(memDef.inverseProperty)) { - //copy member definition - var t = JSON.parse(JSON.stringify(memDef)); - //change datatype to resolved type - t.dataType = memDefResolvedDataType; - dbEntityInstanceDefinition[memDef.name] = t; - continue; - } - - this._buildDbType_navigationPropertyComplite(memDef, memDefResolvedDataType, storageModel); - - //var memDef_dataType = this.getDataType(memDef.dataType); - if ((memDefResolvedDataType === $data.Array || (memDefResolvedDataType.isAssignableTo && memDefResolvedDataType.isAssignableTo($data.EntitySet))) && - (memDef.inverseProperty && memDef.inverseProperty !== '$$unbound')) { - this._buildDbType_Collection_OneManyDefinition(dbEntityInstanceDefinition, storageModel, memDefResolvedDataType, memDef); - } else { - if (memDef.inverseProperty) { - if (memDef.inverseProperty === '$$unbound') { - //member definition is navigation but not back reference - if (memDefResolvedDataType === $data.Array) { - this._buildDbType_Collection_OneManyDefinition(dbEntityInstanceDefinition, storageModel, memDefResolvedDataType, memDef); - } else { - this._buildDbType_ElementType_OneManyDefinition(dbEntityInstanceDefinition, storageModel, memDefResolvedDataType, memDef); - } - } else { - //member definition is navigation property one..one or one..many case - var fields = memDefResolvedDataType.memberDefinitions.getMember(memDef.inverseProperty); - if (fields) { - if (fields.elementType) { - //member definition is one..many connection - var referealResolvedType = Container.resolveType(fields.elementType); - if (referealResolvedType === storageModel.LogicalType) { - this._buildDbType_ElementType_OneManyDefinition(dbEntityInstanceDefinition, storageModel, memDefResolvedDataType, memDef); - } else { - if (typeof intellisense === 'undefined') { - Guard.raise(new Exception('Inverse property not valid, refereed item element type not match: ' + storageModel.LogicalTypeName, ', property: ' + memDef.name)); - } - } - } else { - //member definition is one..one connection - this._buildDbType_ElementType_OneOneDefinition(dbEntityInstanceDefinition, storageModel, memDefResolvedDataType, memDef); - } - } else { - if (typeof intellisense === 'undefined') { - Guard.raise(new Exception('Inverse property not valid')); - } - } - } - } else { - //member definition is a complex type - this._buildDbType_addComplexTypePropertyDefinition(dbEntityInstanceDefinition, storageModel, memDefResolvedDataType, memDef); - } - } - } - this._buildDbType_modifyInstanceDefinition(dbEntityInstanceDefinition, storageModel, this); - var dbEntityClassDefinition = {}; - dbEntityClassDefinition.convertTo = this._buildDbType_generateConvertToFunction(storageModel, this); - this._buildDbType_modifyClassDefinition(dbEntityClassDefinition, storageModel, this); - - //create physical type - //TODO - storageModel.PhysicalType = $data.Class.define(storageModel.PhysicalTypeName, $data.Entity, storageModel.LogicalType.container, dbEntityInstanceDefinition, dbEntityClassDefinition); - } - }, - _initializeActions: function (es, ctor, esDef) { - if (esDef && esDef.actions) { - var actionKeys = Object.keys(esDef.actions); - for (var i = 0; i < actionKeys.length; i++) { - var actionName = actionKeys[i]; - var action = esDef.actions[actionName]; - if (typeof action === 'function') { - es[actionName] = action; - } else { - var actionDef = $data.MemberDefinition.translateDefinition(action, actionName, ctor); - if (actionDef instanceof $data.MemberDefinition && actionDef.kind === $data.MemberTypes.method) { - es[actionName] = actionDef.method; - } - } - } - } - }, - _buildDbType_navigationPropertyComplite: function (memDef, memDefResolvedDataType, storageModel) { - if (!memDef.inverseProperty) { - var refMemDefs = null; - if (memDefResolvedDataType === $data.Array || (memDefResolvedDataType.isAssignableTo && memDefResolvedDataType.isAssignableTo($data.EntitySet))) { - var refStorageModel = this._storageModel.getStorageModel(Container.resolveType(memDef.elementType)); - if (refStorageModel) { - refMemDefs = []; - var pubDefs = refStorageModel.LogicalType.memberDefinitions.getPublicMappedProperties(); - for (var i = 0; i < pubDefs.length; i++) { - var m = pubDefs[i]; - if ((m.inverseProperty == memDef.name) && (Container.resolveType(m.dataType) === Container.resolveType(storageModel.LogicalType))) - refMemDefs.push(m); - } - } - } else { - var refStorageModel = this._storageModel.getStorageModel(memDefResolvedDataType); - if (refStorageModel) { - refMemDefs = []; - var pubDefs = refStorageModel.LogicalType.memberDefinitions.getPublicMappedProperties(); - for (var i = 0; i < pubDefs.length; i++) { - var m = pubDefs[i]; - if (m.elementType && ((m.inverseProperty == memDef.name) && (Container.resolveType(m.elementType) === storageModel.LogicalType))) - refMemDefs.push(m); - else if ((m.inverseProperty == memDef.name) && (Container.resolveType(m.dataType) === storageModel.LogicalType)) - refMemDefs.push(m); - } - } - } - if (refMemDefs) { - if (refMemDefs.length > 1) { - if (typeof intellisense !== 'undefined') { - Guard.raise(new Exception('More than one inverse property refer to this member definition: ' + memDef.name + ', type: ' + Container.resolveName(storageModel.LogicalType))); - } - } - var refMemDef = refMemDefs.pop(); - if (refMemDef) { - memDef.inverseProperty = refMemDef.name; - } - } - } else { - var refStorageModel = null; - if (memDefResolvedDataType === $data.Array || (memDefResolvedDataType.isAssignableTo && memDefResolvedDataType.isAssignableTo($data.EntitySet))) { - refStorageModel = this._storageModel.getStorageModel(Container.resolveType(memDef.elementType)); - - } else { - refStorageModel = this._storageModel.getStorageModel(memDefResolvedDataType); - } - - var p = refStorageModel.LogicalType.memberDefinitions.getMember(memDef.inverseProperty); - if (p) { - if (p.inverseProperty) { - if (p.inverseProperty != memDef.name) { - if (typeof intellisense === 'undefined') { - Guard.raise(new Exception('Inverse property mismatch')); - } - } - } else { - p.inverseProperty = memDef.name; - } - } - - } - }, - _buildDbType_generateConvertToFunction: function (storageModel) { return function (instance) { return instance; }; }, - _buildDbType_modifyInstanceDefinition: function (instanceDefinition, storageModel) { return; }, - _buildDbType_modifyClassDefinition: function (classDefinition, storageModel) { return; }, - _buildDbType_addComplexTypePropertyDefinition: function (dbEntityInstanceDefinition, storageModel, memDef_dataType, memDef) { - this._addNavigationPropertyDefinition(dbEntityInstanceDefinition, memDef, memDef.name, $data.MemberTypes.complexProperty); - var complexType = this._createComplexElement(storageModel.LogicalType, "", memDef.name, memDef_dataType, "", ""); - storageModel.ComplexTypes[memDef.name] = complexType; - storageModel.ComplexTypes.push(complexType); - }, - _buildDbType_Collection_OneManyDefinition: function (dbEntityInstanceDefinition, storageModel, memDef_dataType, memDef) { - var refereedType = Container.resolveType(memDef.elementType); - if (refereedType === undefined || refereedType === null) { - if (typeof intellisense === 'undefined') { - Guard.raise(new Exception("Element type definition error", "Field definition", memDef)); - } - } - var refereedStorageModel = this._storageModel.getStorageModel(refereedType); - //var refereedStorageModel = this._storageModel.filter(function (s) { return s.LogicalType === refereedType; })[0]; - if (!refereedStorageModel) { - if (typeof intellisense === 'undefined') { - Guard.raise(new Exception("No EntitySet definition for the following element type", "Field definition", memDef)); - } - } - - this._addNavigationPropertyDefinition(dbEntityInstanceDefinition, memDef, memDef.name); - var associationType = memDef.inverseProperty === '$$unbound' ? '$$unbound' : '0..1'; - var association = this._addAssociationElement(storageModel.LogicalType, associationType, memDef.name, refereedStorageModel.LogicalType, "*", memDef.inverseProperty); - storageModel.Associations[memDef.name] = association; - storageModel.Associations.push(association); - }, - _buildDbType_ElementType_OneManyDefinition: function (dbEntityInstanceDefinition, storageModel, memDef_dataType, memDef) { - var refereedType = Container.resolveType(memDef.dataType); - if (refereedType === undefined || refereedType === null) { - if (typeof intellisense === 'undefined') { - Guard.raise(new Exception("Element type definition error", "Field definition", memDef)); - } - } - var refereedStorageModel = this._storageModel.getStorageModel(refereedType); - //var refereedStorageModel = this._storageModel.filter(function (s) { return s.LogicalType === refereedType; })[0]; - if (!refereedStorageModel) { - if (typeof intellisense === 'undefined') { - Guard.raise(new Exception("No EntitySet definition for the following element type", "Field definition", memDef)); - } - } - - this._addNavigationPropertyDefinition(dbEntityInstanceDefinition, memDef, memDef.name); - var associationType = memDef.inverseProperty === '$$unbound' ? '$$unbound' : '*'; - var association = this._addAssociationElement(storageModel.LogicalType, associationType, memDef.name, refereedStorageModel.LogicalType, "0..1", memDef.inverseProperty); - storageModel.Associations[memDef.name] = association; - storageModel.Associations.push(association); - }, - _buildDbType_ElementType_OneOneDefinition: function (dbEntityInstanceDefinition, storageModel, memDef_dataType, memDef) { - var refereedType = Container.resolveType(memDef.dataType); - if (refereedType === undefined || refereedType === null) { - if (typeof intellisense === 'undefined') { - Guard.raise(new Exception("Element type definition error", "Field definition", memDef)); - } - } - var refereedStorageModel = this._storageModel.getStorageModel(refereedType);; - //var refereedStorageModel = this._storageModel.filter(function (s) { return s.LogicalType === refereedType; })[0]; - if (!refereedStorageModel) { - if (typeof intellisense === 'undefined') { - Guard.raise(new Exception("No EntitySet definition following element type", "Field definition", memDef)); - } - } - - var refereedMemberDefinition = refereedStorageModel.LogicalType.memberDefinitions.getMember(memDef.inverseProperty); - if (!refereedMemberDefinition.required && !memDef.required) { if (typeof intellisense === 'undefined') { if (typeof intellisense === 'undefined') { Guard.raise(new Exception('In one to one connection, one side must required!', 'One to One connection', memDef)); } } } - - this._addNavigationPropertyDefinition(dbEntityInstanceDefinition, memDef, memDef.name); - - var association = this._addAssociationElement(storageModel.LogicalType, - memDef.required ? "0..1" : "1", - memDef.name, - refereedStorageModel.LogicalType, - memDef.required ? "1" : "0..1", - memDef.inverseProperty); - storageModel.Associations[memDef.name] = association; - storageModel.Associations.push(association); - }, - _addNavigationPropertyDefinition: function (definition, member, associationName, kind) { - var t = JSON.parse(JSON.stringify(member)); - t.dataType = $data.EntitySet; - t.notMapped = true; - t.kind = kind ? kind : $data.MemberTypes.navProperty; - t.association = associationName; - definition[member.name] = t; - }, - _addAssociationElement: function (fromType, fromMultiplicity, fromPropName, toType, toMultiplicity, toPropName) { - return new $data.Association({ - From: fromType.name, - FromType: fromType, - FromMultiplicity: fromMultiplicity, - FromPropertyName: fromPropName, - To: toType.name, - ToType: toType, - ToMultiplicity: toMultiplicity, - ReferentialConstraint: [], - ToPropertyName: toPropName - }); - }, - _createComplexElement: function (fromType, fromMultiplicity, fromPropName, toType, toMultiplicity, toPropName) { - return new $data.ComplexType({ - From: fromType.name, - FromType: fromType, - FromMultiplicity: fromMultiplicity, - FromPropertyName: fromPropName, - To: toType.name, - ToType: toType, - ToMultiplicity: toMultiplicity, - ReferentialConstraint: [], - ToPropertyName: toPropName - }); - }, - - _successInitProvider: function (context, error) { - if (context instanceof $data.EntityContext && context._isOK !== undefined) { - if (!error) { - context._isOK = true; - if (context.onReadyFunction) { - for (var i = 0; i < context.onReadyFunction.length; i++) { - context.onReadyFunction[i].success(context); - } - context.onReadyFunction = undefined; - } - } else { - context._isOK = error; - if (context.onReadyFunction) { - for (var i = 0; i < context.onReadyFunction.length; i++) { - context.onReadyFunction[i].error(error); - } - context.onReadyFunction = undefined; - } - } - } - }, - onReady: function (fn) { - /// - /// - /// Sets the callback function to be called when the initialization of the EntityContext has successfully finished. - /// - /// - /// Success callback - /// Current entityContext object - /// - /// - /// - /// - /// - /// Sets the callback functions to be called when the initialization of the EntityContext has finished. - /// - /// - /// Success and error callbacks definition. - /// Example: [code]{ success: function(db) { .. }, error: function() { .. } }[/code] - /// - /// - /// - var pHandler = new $data.PromiseHandler(); - var callBack = pHandler.createCallback(fn); - if (this._isOK === true) { - callBack.success(this); - } else if (this._isOK !== false) { - callBack.error(this._isOK); - } else { - this.onReadyFunction = this.onReadyFunction || []; - this.onReadyFunction.push(callBack); - } - - return pHandler.getPromise(); - }, - ready: { type: $data.Promise }, - getEntitySetFromElementType: function (elementType) { - /// - /// Gets the matching EntitySet for an element type. - /// - /// - /// - /// - /// Gets the matching EntitySet for an element type. - /// - /// - /// - var result = this._entitySetReferences[elementType]; - if (!result) { - try { - result = this._entitySetReferences[eval(elementType).name]; - } catch (ex) { } - } - return result; - }, - executeQuery: function (queryable, callBack, transaction) { - var query = new $data.Query(queryable.expression, queryable.defaultType, this); - query.transaction = transaction instanceof $data.Transaction ? transaction : undefined; - var returnTransaction = this._isReturnTransaction(transaction); - - callBack = $data.typeSystem.createCallbackSetting(callBack); - var that = this; - var clbWrapper = {}; - clbWrapper.success = function (query) { - if ($data.QueryCache && $data.QueryCache.isCacheable(that, query)) { - $data.QueryCache.addToCache(that, query); - } - - query.buildResultSet(that); - - if ($data.ItemStore && 'QueryResultModifier' in $data.ItemStore) - $data.ItemStore.QueryResultModifier.call(that, query); - - var successResult; - - if (query.expression.nodeType === $data.Expressions.ExpressionType.Single || - query.expression.nodeType === $data.Expressions.ExpressionType.Find || - query.expression.nodeType === $data.Expressions.ExpressionType.Count || - query.expression.nodeType === $data.Expressions.ExpressionType.BatchDelete || - query.expression.nodeType === $data.Expressions.ExpressionType.Some || - query.expression.nodeType === $data.Expressions.ExpressionType.Every) { - if (query.result.length !== 1) { - callBack.error(new Exception('result count failed')); - return; - } - - successResult = query.result[0]; - } else if (query.expression.nodeType === $data.Expressions.ExpressionType.First) { - if (query.result.length === 0) { - callBack.error(new Exception('result count failed')); - return; - } - - successResult = query.result[0]; - } else { - if (typeof query.__count === 'number' && query.result) - query.result.totalCount = query.__count; - - that.storageProvider._buildContinuationFunction(that, query); - - successResult = query.result; - } - - var readyFn = function () { - that._applyTransaction(callBack, callBack.success, [successResult], query.transaction, returnTransaction); - - /*if (returnTransaction === true) { - if (query.transaction) - callBack.success(successResult, query.transaction); - else { - that.beginTransaction(function (tran) { - callBack.success(successResult, tran); - }); - } - } - else - callBack.success(successResult);*/ - }; - - var i = 0; - var sets = query.getEntitySets(); - - var callbackFn = function () { - var es = sets[i]; - if (es.afterRead) { - i++; - var r = es.afterRead.call(this, successResult, sets, query); - if (typeof r === 'function') { - r.call(this, i < sets.length ? callbackFn : readyFn, successResult, sets, query); - } else { - if (i < sets.length) { - callbackFn(); - } else readyFn(); - } - } else readyFn(); - } - - if (sets.length) callbackFn(); - else readyFn(); - }; - - clbWrapper.error = function () { - if(returnTransaction) - callBack.error.apply(this, arguments); - else - callBack.error.apply(this, Array.prototype.filter.call(arguments, function (p) { return !(p instanceof $data.Transaction); })); - }; - var sets = query.getEntitySets(); - - var authorizedFn = function () { - var ex = true; - var wait = false; - var ctx = that; - - var readyFn = function (cancel) { - if (cancel === false) ex = false; - - if (ex) { - if (query.transaction) { - if ($data.QueryCache && $data.QueryCache.isInCache(that, query)) { - $data.QueryCache.executeQuery(that, query, clbWrapper); - } else { - ctx.storageProvider.executeQuery(query, clbWrapper); - } - } else { - ctx.beginTransaction(function (tran) { - query.transaction = tran; - if ($data.QueryCache && $data.QueryCache.isInCache(that, query)) { - $data.QueryCache.executeQuery(that, query, clbWrapper); - } else { - ctx.storageProvider.executeQuery(query, clbWrapper); - } - }); - } - } else { - query.rawDataList = []; - query.result = []; - clbWrapper.success(query); - } - }; - - var i = 0; - var callbackFn = function (cancel) { - if (cancel === false) ex = false; - - var es = sets[i]; - if (es.beforeRead) { - i++; - var r = es.beforeRead.call(this, sets, query); - if (typeof r === 'function') { - r.call(this, (i < sets.length && ex) ? callbackFn : readyFn, sets, query); - } else { - if (r === false) ex = false; - - if (i < sets.length && ex) { - callbackFn(); - } else readyFn(); - } - } else readyFn(); - }; - - if (sets.length) callbackFn(); - else readyFn(); - }; - - if (this.user && this.checkPermission) { - this.checkPermission(query.expression.nodeType === $data.Expressions.ExpressionType.BatchDelete ? $data.Access.DeleteBatch : $data.Access.Read, this.user, sets, { - success: authorizedFn, - error: clbWrapper.error - }); - } else authorizedFn(); - }, - saveChanges: function (callback, transaction) { - /// - /// - /// Saves the changes made to the context. - /// - /// - /// Success callback - /// Current entityContext object - /// - /// - /// - /// - /// - /// Saves the changes made to the context. - /// - /// - /// Success and error callbacks definition. - /// Example: [code]{ success: function(db) { .. }, error: function() { .. } }[/code] - /// - /// - /// - - if ($data.QueryCache) { - $data.QueryCache.reset(this); - } - - var changedEntities = []; - var trackedEntities = this.stateManager.trackedEntities; - var pHandler = new $data.PromiseHandler(); - var clbWrapper = pHandler.createCallback(callback); - var pHandlerResult = pHandler.getPromise(); - var returnTransaction = this._isReturnTransaction(transaction); - - var skipItems = []; - while (trackedEntities.length > 0) { - var additionalEntities = []; - //trackedEntities.forEach(function (entityCachedItem) { - for (var i = 0; i < trackedEntities.length; i++) { - var entityCachedItem = trackedEntities[i]; - - var sModel = this._storageModel.getStorageModel(entityCachedItem.data.getType()); - if (entityCachedItem.data.entityState == $data.EntityState.Unchanged) { - entityCachedItem.skipSave = true; - skipItems.push(entityCachedItem.data); - } else { - if (entityCachedItem.data.entityState == $data.EntityState.Modified) { - if (entityCachedItem.data.changedProperties) { - var changeStoredProperty = entityCachedItem.data.changedProperties.some(function (p) { - var pMemDef = sModel.PhysicalType.memberDefinitions.getMember(p.name); - if (pMemDef.kind == $data.MemberTypes.navProperty) { - var a = sModel.Associations[pMemDef.association]; - var multiplicity = a.FromMultiplicity + a.ToMultiplicity; - return ((multiplicity == '*0..1') || (multiplicity == '0..11')) - } - return true; - }); - if (!changeStoredProperty) { - entityCachedItem.skipSave = true; - skipItems.push(entityCachedItem.data); - } - } - } - } - - //type before events with items - this.processEntityTypeBeforeEventHandler(skipItems, entityCachedItem); - - var navigationProperties = []; - var smPhyMemDefs = sModel.PhysicalType.memberDefinitions.asArray(); - for (var ism = 0; ism < smPhyMemDefs.length; ism++) { - var p = smPhyMemDefs[ism]; - if (p.kind == $data.MemberTypes.navProperty) - navigationProperties.push(p); - } - //var navigationProperties = sModel.PhysicalType.memberDefinitions.asArray().filter(function (p) { return p.kind == $data.MemberTypes.navProperty; }); - //navigationProperties.forEach(function (navProp) { - for (var j = 0; j < navigationProperties.length; j++) { - var navProp = navigationProperties[j]; - - var association = sModel.Associations[navProp.name]; //eg.:"Profile" - var name = navProp.name; //eg.: "Profile" - var navPropertyName = association.ToPropertyName; //eg.: User - - var connectedDataList = [].concat(entityCachedItem.data[name]); - //connectedDataList.forEach(function (data) { - for (var k = 0; k < connectedDataList.length; k++) { - var data = connectedDataList[k]; - - if (data) { - var value = data[navPropertyName]; - var associationType = association.FromMultiplicity + association.ToMultiplicity; - if (association.FromMultiplicity === '$$unbound') { - if (data instanceof $data.Array) { - entityCachedItem.dependentOn = entityCachedItem.dependentOn || []; - //data.forEach(function (dataItem) { - for (var l = 0; l < data.length; l++) { - var dataItem = data[l]; - - if ((entityCachedItem.dependentOn.indexOf(data) < 0) && (data.skipSave !== true)) { - entityCachedItem.dependentOn.push(data); - } - } - //}, this); - } else { - entityCachedItem.dependentOn = entityCachedItem.dependentOn || []; - if ((entityCachedItem.dependentOn.indexOf(data) < 0) && (data.skipSave !== true)) { - entityCachedItem.dependentOn.push(data); - } - } - } else { - switch (associationType) { - case "*0..1": //Array - if (value) { - if (value instanceof Array) { - if (value.indexOf(entityCachedItem.data) == -1) { - value.push(entityCachedItem.data); - data.initData[navPropertyName] = value; - data._setPropertyChanged(association.ToType.getMemberDefinition(navPropertyName)); - } - } else { - if (typeof intellisense === 'undefined') { - Guard.raise("Item must be array or subtype of array"); - } - } - } else { - data.initData[navPropertyName] = [entityCachedItem.data]; - data._setPropertyChanged(association.ToType.getMemberDefinition(navPropertyName)); - } - break; - default: //Item - if (value) { - if (value !== entityCachedItem.data) { - if (typeof intellisense === 'undefined') { - Guard.raise("Integrity check error! Item assigned to another entity!"); - } - } - } else { - data.initData[navPropertyName] = entityCachedItem.data; //set back reference for live object - data._setPropertyChanged(association.ToType.getMemberDefinition(navPropertyName)); - } - break; - } - switch (associationType) { - case "*0..1": - case "0..11": - entityCachedItem.dependentOn = entityCachedItem.dependentOn || []; - if ((entityCachedItem.dependentOn.indexOf(data) < 0) && (data.skipSave !== true)) { - entityCachedItem.dependentOn.push(data); - } - break; - } - } - if (!data.entityState) { - if (data.storeToken === this.storeToken) { - data.entityState = $data.EntityState.Modified; - } else { - data.entityState = $data.EntityState.Added; - } - } - if (additionalEntities.indexOf(data) == -1) { - additionalEntities.push(data); - } - } - } - //}, this); - } - //}, this); - } - //}, this); - - //trackedEntities.forEach(function (entity) { - for (var i = 0; i < trackedEntities.length; i++) { - var entity = trackedEntities[i]; - - if (entity.skipSave !== true) { changedEntities.push(entity); } - } - //}); - - trackedEntities = []; - //additionalEntities.forEach(function (item) { - for (var i = 0; i < additionalEntities.length; i++) { - var item = additionalEntities[i]; - - if (!skipItems.some(function (entity) { return entity == item; })) { - if (!changedEntities.some(function (entity) { return entity.data == item; })) { - trackedEntities.push({ data: item, entitySet: this.getEntitySetFromElementType(item.getType().name) }); - } - } - } - //}, this); - } - - - //changedEntities.forEach(function (d) { - for (var j = 0; j < changedEntities.length; j++) { - var d = changedEntities[j]; - - if (d.dependentOn) { - var temp = []; - for (var i = 0; i < d.dependentOn.length; i++) { - if (skipItems.indexOf(d.dependentOn[i]) < 0) { - temp.push(d.dependentOn[i]); - } - } - d.dependentOn = temp; - } - } - //}); - skipItems = null; - var ctx = this; - if (changedEntities.length == 0) { - this.stateManager.trackedEntities.length = 0; - ctx._applyTransaction(clbWrapper, clbWrapper.success, [0], transaction, returnTransaction); - - /*if (returnTransaction) { - clbWrapper.success(0, transaction); - } else { - clbWrapper.success(0); - }*/ - return pHandlerResult; - } - - //validate entities - var errors = []; - //changedEntities.forEach(function (entity) { - for (var i = 0; i < changedEntities.length; i++) { - var entity = changedEntities[i]; - - if (entity.data.entityState === $data.EntityState.Added) { - //entity.data.getType().memberDefinitions.getPublicMappedProperties().forEach(function (memDef) { - for (var j = 0; j < entity.data.getType().memberDefinitions.getPublicMappedProperties().length; j++) { - var memDef = entity.data.getType().memberDefinitions.getPublicMappedProperties()[j]; - - var memDefType = Container.resolveType(memDef.type); - if (memDef.required && !memDef.computed && !entity.data[memDef.name] && !memDef.isDependentProperty) { - switch (memDefType) { - case $data.String: - case $data.Number: - case $data.Float: - case $data.Decimal: - case $data.Integer: - case $data.Int16: - case $data.Int32: - case $data.Int64: - case $data.Byte: - case $data.SByte: - case $data.Date: - case $data.Boolean: - entity.data[memDef.name] = Container.getDefault(memDef.dataType); - break; - default: - break; - } - } - } - //}, this); - } - if ((entity.data.entityState === $data.EntityState.Added || entity.data.entityState === $data.EntityState.Modified) - && !entity.data.isValid()) { - errors.push({ item: entity.data, errors: entity.data.ValidationErrors }); - } - } - //}); - if (errors.length > 0) { - clbWrapper.error(errors); - return pHandlerResult; - } - - var access = $data.Access.None; - - var eventData = {}; - var sets = []; - for (var i = 0; i < changedEntities.length; i++) { - var it = changedEntities[i]; - var n = it.entitySet.elementType.name; - if (sets.indexOf(it.entitySet) < 0) sets.push(it.entitySet); - var es = this._entitySetReferences[n]; - if (es.beforeCreate || es.beforeUpdate || es.beforeDelete || (this.user && this.checkPermission)) { - if (!eventData[n]) eventData[n] = {}; - - switch (it.data.entityState) { - case $data.EntityState.Added: - access |= $data.Access.Create; - if (es.beforeCreate) { - if (!eventData[n].createAll) eventData[n].createAll = []; - eventData[n].createAll.push(it); - } - break; - case $data.EntityState.Modified: - access |= $data.Access.Update; - if (es.beforeUpdate) { - if (!eventData[n].modifyAll) eventData[n].modifyAll = []; - eventData[n].modifyAll.push(it); - } - break; - case $data.EntityState.Deleted: - access |= $data.Access.Delete; - if (es.beforeDelete) { - if (!eventData[n].deleteAll) eventData[n].deleteAll = []; - eventData[n].deleteAll.push(it); - } - break; - } - } - } - - var readyFn = function (cancel) { - if (cancel === false) { - cancelEvent = 'async'; - changedEntities.length = 0; - } - - if (changedEntities.length) { - //console.log('changedEntities: ', changedEntities.map(function(it){ return it.data.initData; })); - - var innerCallback = { - success: function (tran) { - ctx._postProcessSavedItems(clbWrapper, changedEntities, tran, returnTransaction); - }, - error: function () { - //TODO remove trans from args; - if (returnTransaction) - clbWrapper.error.apply(this, arguments); - else - clbWrapper.error.apply(this, Array.prototype.filter.call(arguments, function (p) { return !(p instanceof $data.Transaction); })); - } - }; - - if (transaction instanceof $data.Transaction){ - ctx.storageProvider.saveChanges(innerCallback, changedEntities, transaction); - } else { - ctx.beginTransaction(true, function (tran) { - ctx.storageProvider.saveChanges(innerCallback, changedEntities, tran); - }); - } - } else if (cancelEvent) { - clbWrapper.error(new Exception('Cancelled event in ' + cancelEvent, 'CancelEvent')); - } else { - ctx._applyTransaction(clbWrapper, clbWrapper.success, [0], transaction, returnTransaction); - - /*if(returnTransaction) - clbWrapper.success(0, transaction); - else - clbWrapper.success(0);*/ - }; - - /*else if (cancelEvent) clbWrapper.error(new $data.Exception('saveChanges cancelled from event [' + cancelEvent + ']')); - else Guard.raise('No changed entities');*/ - }; - - var cancelEvent; - var ies = Object.getOwnPropertyNames(eventData); - var i = 0; - var cmd = ['beforeUpdate', 'beforeDelete', 'beforeCreate']; - var cmdAll = { - beforeCreate: 'createAll', - beforeDelete: 'deleteAll', - beforeUpdate: 'modifyAll' - }; - - var callbackFn = function (cancel) { - if (cancel === false) { - cancelEvent = 'async'; - changedEntities.length = 0; - - readyFn(cancel); - return; - } - - var es = ctx._entitySetReferences[ies[i]]; - var c = cmd.pop(); - var ed = eventData[ies[i]]; - var all = ed[cmdAll[c]]; - - if (all) { - var m = []; - for (var im = 0; im < all.length; im++) { - m.push(all[im].data); - } - //var m = all.map(function(it){ return it.data; }); - if (!cmd.length) { - cmd = ['beforeUpdate', 'beforeDelete', 'beforeCreate']; - i++; - } - - var r = es[c].call(ctx, m); - if (typeof r === 'function') { - r.call(ctx, (i < ies.length && !cancelEvent) ? callbackFn : readyFn, m); - } else if (r === false) { - cancelEvent = (es.name + '.' + c); - //all.forEach(function (it) { - for (var index = 0; index < all.length; index++) { - var it = all[index]; - - var ix = changedEntities.indexOf(it); - changedEntities.splice(ix, 1); - } - //}); - - readyFn(); - } else { - if (i < ies.length && !cancelEvent) callbackFn(); - else readyFn(); - } - } else { - if (!cmd.length) { - cmd = ['beforeUpdate', 'beforeDelete', 'beforeCreate']; - i++; - } - - if (i < ies.length && !cancelEvent) callbackFn(); - else readyFn(); - } - }; - - if (this.user && this.checkPermission) { - this.checkPermission(access, this.user, sets, { - success: function () { - if (i < ies.length) callbackFn(); - else readyFn(); - }, - error: clbWrapper.error - }); - } else { - if (i < ies.length) callbackFn(); - else readyFn(); - } - - return pHandlerResult; - }, - - processEntityTypeBeforeEventHandler: function (skipItems, entityCachedItem) { - if (!entityCachedItem.skipSave) { - var entity = entityCachedItem.data; - var entityType = entity.getType(); - var state = entity.entityState; - - switch (true) { - case state === $data.EntityState.Added && entityType.onbeforeCreate instanceof $data.Event: - if (entityType.onbeforeCreate.fireCancelAble(entity) === false) { - entityCachedItem.skipSave = true; - skipItems.push(entity); - } - break; - case state === $data.EntityState.Modified && entityType.onbeforeUpdate instanceof $data.Event: - if (entityType.onbeforeUpdate.fireCancelAble(entity) === false) { - entityCachedItem.skipSave = true; - skipItems.push(entity); - } - break; - case state === $data.EntityState.Deleted && entityType.onbeforeDelete instanceof $data.Event: - if (entityType.onbeforeDelete.fireCancelAble(entity) === false) { - entityCachedItem.skipSave = true; - skipItems.push(entity); - } - break; - default: - break; - } - } - }, - processEntityTypeAfterEventHandler: function (entityCachedItem) { - var entity = entityCachedItem.data; - var entityType = entity.getType(); - var state = entity.entityState; - - switch (true) { - case state === $data.EntityState.Added && entityType.onafterCreate instanceof $data.Event: - entityType.onafterCreate.fire(entity); - break; - case state === $data.EntityState.Modified && entityType.onafterUpdate instanceof $data.Event: - entityType.onafterUpdate.fire(entity); - break; - case state === $data.EntityState.Deleted && entityType.onafterDelete instanceof $data.Event: - entityType.onafterDelete.fire(entity); - break; - default: - break; - } - }, - - bulkInsert: function (entitySet, fields, datas, callback) { - var pHandler = new $data.PromiseHandler(); - callback = pHandler.createCallback(callback); - if (typeof entitySet === 'string') { - var currentEntitySet; - - for (var entitySetName in this._entitySetReferences) { - var actualEntitySet = this._entitySetReferences[entitySetName]; - if (actualEntitySet.tableName === entitySet) { - currentEntitySet = actualEntitySet; - break; - } - } - - if (!currentEntitySet) - currentEntitySet = this[entitySet]; - - entitySet = currentEntitySet; - } - if (entitySet) { - this.storageProvider.bulkInsert(entitySet, fields, datas, callback); - } else { - callback.error(new Exception('EntitySet not found')); - } - return pHandler.getPromise(); - }, - - prepareRequest: function () { }, - _postProcessSavedItems: function (callBack, changedEntities, transaction, returnTransaction) { - if (this.ChangeCollector && this.ChangeCollector instanceof $data.Notifications.ChangeCollectorBase) - this.ChangeCollector.processChangedData(changedEntities); - - var eventData = {}; - var ctx = this; - //changedEntities.forEach(function (entity) { - for (var i = 0; i < changedEntities.length; i++) { - var entity = changedEntities[i]; - - if (!entity.data.storeToken) - entity.data.storeToken = ctx.storeToken; - - //type after events with items - this.processEntityTypeAfterEventHandler(entity); - - var oes = entity.data.entityState; - - entity.data.entityState = $data.EntityState.Unchanged; - entity.data.changedProperties = []; - entity.physicalData = undefined; - - var n = entity.entitySet.elementType.name; - var es = ctx._entitySetReferences[n]; - - - var eventName = undefined; - switch (oes) { - case $data.EntityState.Added: - eventName = 'added'; - break; - case $data.EntityState.Deleted: - eventName = 'deleted'; - break; - case $data.EntityState.Modified: - eventName = 'updated'; - break; - } - if (eventName) { - this.raiseEvent(eventName, entity); - } - - if (es.afterCreate || es.afterUpdate || es.afterDelete) { - if (!eventData[n]) eventData[n] = {}; - - switch (oes) { - case $data.EntityState.Added: - if (es.afterCreate) { - if (!eventData[n].createAll) eventData[n].createAll = []; - eventData[n].createAll.push(entity); - } - break; - case $data.EntityState.Modified: - if (es.afterUpdate) { - if (!eventData[n].modifyAll) eventData[n].modifyAll = []; - eventData[n].modifyAll.push(entity); - } - break; - case $data.EntityState.Deleted: - if (es.afterDelete) { - if (!eventData[n].deleteAll) eventData[n].deleteAll = []; - eventData[n].deleteAll.push(entity); - } - break; - } - } - } - //}); - - var ies = Object.getOwnPropertyNames(eventData); - var i = 0; - var ctx = this; - var cmd = ['afterUpdate', 'afterDelete', 'afterCreate']; - var cmdAll = { - afterCreate: 'createAll', - afterDelete: 'deleteAll', - afterUpdate: 'modifyAll' - }; - - var readyFn = function () { - if (!ctx.trackChanges) { - ctx.stateManager.reset(); - } - - ctx._applyTransaction(callBack, callBack.success, [changedEntities.length], transaction, returnTransaction); - - /*if (returnTransaction) - callBack.success(changedEntities.length, transaction); - else - callBack.success(changedEntities.length);*/ - }; - - var callbackFn = function () { - var es = ctx._entitySetReferences[ies[i]]; - var c = cmd.pop(); - var ed = eventData[ies[i]]; - var all = ed[cmdAll[c]]; - if (all) { - var m = []; - for (var im = 0; im < all.length; im++) { - m.push(all[im].data); - } - //var m = all.map(function(it){ return it.data; }); - if (!cmd.length) { - cmd = ['afterUpdate', 'afterDelete', 'afterCreate']; - i++; - } - - var r = es[c].call(ctx, m); - if (typeof r === 'function') { - r.call(ctx, i < ies.length ? callbackFn : readyFn, m); - } else { - if (i < ies.length) callbackFn(); - else readyFn(); - } - } else { - if (!cmd.length) { - cmd = ['afterUpdate', 'afterDelete', 'afterCreate']; - i++; - } - - if (i < ies.length) callbackFn(); - else readyFn(); - } - }; - - if (i < ies.length) callbackFn(); - else readyFn(); - }, - forEachEntitySet: function (fn, ctx) { - /// - /// Iterates over the entity sets' of current EntityContext. - /// - /// - /// - /// - /// 'this' argument for the 'fn' function. - for (var entitySetName in this._entitySetReferences) { - var actualEntitySet = this._entitySetReferences[entitySetName]; - fn.call(ctx, actualEntitySet); - } - }, - - loadItemProperty: function (entity, property, callback, transaction) { - /// - /// Loads a property of the entity through the storage provider. - /// Entity object - /// Property name - /// - /// C allback function - /// - /// - /// - /// - /// - /// Loads a property of the entity through the storage provider. - /// Entity object - /// Property name - /// - /// Success and error callbacks definition. - /// Example: [code]{ success: function(db) { .. }, error: function() { .. } }[/code] - /// - /// - /// - /// - /// Loads a property of the entity through the storage provider. - /// Entity object - /// Property definition - /// - /// Callback function - /// - /// - /// - /// - /// - /// Loads a property of the entity through the storage provider. - /// Entity object - /// Property definition - /// - /// Success and error callbacks definition. - /// Example: [code]{ success: function(db) { .. }, error: function() { .. } }[/code] - /// - /// - /// - Guard.requireType('entity', entity, $data.Entity); - - var memberDefinition = typeof property === 'string' ? entity.getType().memberDefinitions.getMember(property) : property; - var returnTransaction = this._isReturnTransaction(transaction); - - if (entity[memberDefinition.name] != undefined) { - - var pHandler = new $data.PromiseHandler(); - callBack = pHandler.createCallback(callback); - this._applyTransaction(callback, callback.success, [entity[memberDefinition.name]], transaction, returnTransaction); - /*if (returnTransaction) - callback.success(entity[memberDefinition.name], transaction); - else - callback.success(entity[memberDefinition.name]);*/ - - return pHandler.getPromise(); - } - - var isSingleSide = true; - var storageModel = this._storageModel.getStorageModel(entity.getType().fullName); - var elementType = Container.resolveType(memberDefinition.dataType); - if (elementType === $data.Array || (elementType.isAssignableTo && elementType.isAssignableTo($data.EntitySet))) { - elementType = Container.resolveType(memberDefinition.elementType); - - isSingleSide = false; - - } else { - var associations; - for (var i = 0; i < storageModel.Associations.length; i++) { - var assoc = storageModel.Associations[i]; - if (assoc.FromPropertyName == memberDefinition.name) { - associations = assoc; - break; - } - } - //var associations = storageModel.Associations.filter(function (assoc) { return assoc.FromPropertyName == memberDefinition.name; })[0]; - if (associations && associations.FromMultiplicity === "0..1" && associations.ToMultiplicity === "1") - isSingleSide = false; - } - - var keyProp = storageModel.LogicalType.memberDefinitions.getKeyProperties(); - if (isSingleSide === true) { - //singleSide - - var filterFunc = "function (e) { return"; - var filterParams = {}; - //storageModel.LogicalType.memberDefinitions.getKeyProperties().forEach(function (memDefKey, index) { - for (var index = 0; index < keyProp.length; index++) { - var memDefKey = keyProp[index]; - - if (index > 0) - filterFunc += ' &&'; - filterFunc += " e." + memDefKey.name + " == this.key" + index; - filterParams['key' + index] = entity[memDefKey.name]; - } - //}); - filterFunc += "; }" - - var entitySet = this.getEntitySetFromElementType(entity.getType()); - return entitySet - .map('function (e) { return e.' + memberDefinition.name + ' }') - .single(filterFunc, filterParams, callback, transaction); - } else { - //multipleSide - - var filterFunc = "function (e) { return" - var filterParams = {}; - //storageModel.LogicalType.memberDefinitions.getKeyProperties().forEach(function (memDefKey, index) { - for (var index = 0; index < keyProp.length; index++) { - var memDefKey = keyProp[index]; - - if (index > 0) - filterFunc += ' &&'; - filterFunc += " e." + memberDefinition.inverseProperty + "." + memDefKey.name + " == this.key" + index; - filterParams['key' + index] = entity[memDefKey.name]; - } - //}); - filterFunc += "; }" - - var entitySet = this.getEntitySetFromElementType(elementType); - return entitySet - .filter(filterFunc, filterParams) - .toArray(callback, transaction); - } - - }, - - getTraceString: function (queryable) { - /// - /// Returns a trace string. Used for debugging purposes! - /// - /// - /// Trace string - var query = new $data.Query(queryable.expression, queryable.defaultType, this); - return this.storageProvider.getTraceString(query); - }, - log: function (logInfo) { - //noop as do nothing - }, - - resolveBinaryOperator: function (operator, expression, frameType) { - return this.storageProvider.resolveBinaryOperator(operator, expression, frameType); - }, - resolveUnaryOperator: function (operator, expression, frameType) { - return this.storageProvider.resolveUnaryOperator(operator, expression, frameType); - }, - resolveFieldOperation: function (operation, expression, frameType) { - return this.storageProvider.resolveFieldOperation(operation, expression, frameType); - }, - resolveSetOperations: function (operation, expression, frameType) { - return this.storageProvider.resolveSetOperations(operation, expression, frameType); - }, - resolveTypeOperations: function (operation, expression, frameType) { - return this.storageProvider.resolveTypeOperations(operation, expression, frameType); - }, - resolveContextOperations: function (operation, expression, frameType) { - return this.storageProvider.resolveContextOperations(operation, expression, frameType); - }, - - _generateServiceOperationQueryable: function (functionName, returnEntitySet, arg, parameters) { - if (typeof console !== 'undefined' && console.log) - console.log('Obsolate: _generateServiceOperationQueryable, $data.EntityContext'); - - var params = []; - for (var i = 0; i < parameters.length; i++) { - var obj = {}; - obj[parameters[i]] = Container.resolveType(Container.getTypeName(arg[i])); - params.push(obj); - } - - var tempOperation = $data.EntityContext.generateServiceOperation({ serviceName: functionName, returnType: $data.Queryable, elementType: this[returnEntitySet].elementType, params: params }); - return tempOperation.apply(this, arg); - }, - attach: function (entity, mode) { - /// - /// Attaches an entity to its matching entity set. - /// - /// - /// Returns the attached entity. - - if (entity instanceof $data.EntityWrapper) { - entity = entity.getEntity(); - } - var entitySet = this.getEntitySetFromElementType(entity.getType()); - return entitySet.attach(entity, mode); - }, - attachOrGet: function (entity, mode) { - /// - /// Attaches an entity to its matching entity set, or returns if it's already attached. - /// - /// - /// Returns the entity. - - if (entity instanceof $data.EntityWrapper) { - entity = entity.getEntity(); - } - var entitySet = this.getEntitySetFromElementType(entity.getType()); - return entitySet.attachOrGet(entity, mode); - }, - - addMany: function (entities) { - /// - /// Adds several entities to their matching entity set. - /// - /// - /// Returns the added entities. - var self = this; - entities.forEach(function (entity) { - self.add(entity); - }); - return entities; - }, - - add: function (entity) { - /// - /// Adds a new entity to its matching entity set. - /// - /// - /// Returns the added entity. - - if (entity instanceof $data.EntityWrapper) { - entity = entity.getEntity(); - } - var entitySet = this.getEntitySetFromElementType(entity.getType()); - return entitySet.add(entity); - }, - remove: function (entity) { - /// - /// Removes an entity from its matching entity set. - /// - /// - /// Returns the removed entity. - - if (entity instanceof $data.EntityWrapper) { - entity = entity.getEntity(); - } - var entitySet = this.getEntitySetFromElementType(entity.getType()); - return entitySet.remove(entity); - }, - storeToken: { type: Object }, - - getFieldUrl: function (entity, member, collection) { - try { - var entitySet = typeof collection === 'string' ? this[collection] : collection; - var fieldName = typeof member === 'string' ? member : member.name; - if (entity instanceof $data.Entity) { - entitySet = this.getEntitySetFromElementType(entity.getType()); - } else if (!Object.isNullOrUndefined(entity) && entity.constructor !== $data.Object) { //just a single key - var keyDef = entitySet.elementType.memberDefinitions.getKeyProperties()[0]; - var key = {}; - key[keyDef.name] = entity; - entity = key; - } - - //key object - if (!(entity instanceof $data.Entity)) { - entity = new entitySet.elementType(entity); - } - - return this.storageProvider.getFieldUrl(entity, fieldName, entitySet); - } catch (e) {} - return '#'; - } -}, { - inheritedTypeProcessor: function(type) { - if (type.resolveForwardDeclarations) { - type.resolveForwardDeclarations(); - } - }, - generateServiceOperation: function (cfg) { - - var fn; - if (cfg.serviceMethod) { - var returnType = cfg.returnType ? Container.resolveType(cfg.returnType) : {}; - if (returnType.isAssignableTo && returnType.isAssignableTo($data.Queryable)) { - fn = cfg.serviceMethod; - } else { - fn = function () { - var lastParam = arguments[arguments.length - 1]; - - var pHandler = new $data.PromiseHandler(); - var cbWrapper; - - var args = arguments; - if (typeof lastParam === 'function') { - cbWrapper = pHandler.createCallback(lastParam); - arguments[arguments.length - 1] = cbWrapper; - } else { - cbWrapper = pHandler.createCallback(); - arguments.push(cbWrapper); - } - - try { - var result = cfg.serviceMethod.apply(this, arguments); - if (result !== undefined) - cbWrapper.success(result); - } catch (e) { - cbWrapper.error(e); - } - - return pHandler.getPromise(); - } - } - - } else { - fn = function () { - var context = this; - - var boundItem; - if (this instanceof $data.Entity) { - if (!cfg.method) { - cfg.method = 'POST'; - } - - if (this.context) { - context = this.context; - } else { - Guard.raise('entity not attached into context'); - return; - } - - boundItem = { - data: this, - entitySet: context.getEntitySetFromElementType(this.getType()) - }; - } - - var virtualEntitySet = cfg.elementType ? context.getEntitySetFromElementType(Container.resolveType(cfg.elementType)) : null; - - var paramConstExpression = null; - if (cfg.params) { - paramConstExpression = []; - for (var i = 0; i < cfg.params.length; i++) { - //TODO: check params type - for (var name in cfg.params[i]) { - paramConstExpression.push(Container.createConstantExpression(arguments[i], Container.resolveType(cfg.params[i][name]), name)); - } - } - } - - var ec = Container.createEntityContextExpression(context); - var memberdef = (boundItem ? boundItem.data : context).getType().getMemberDefinition(cfg.serviceName); - var es = Container.createServiceOperationExpression(ec, - Container.createMemberInfoExpression(memberdef), - paramConstExpression, - cfg, - boundItem); - - //Get callback function - var clb = arguments[arguments.length - 1]; - if (typeof clb !== 'function') { - clb = undefined; - } - - if (virtualEntitySet) { - var q = Container.createQueryable(virtualEntitySet, es); - if (clb) { - es.isTerminated = true; - return q._runQuery(clb); - } - return q; - } - else { - var returnType = cfg.returnType ? Container.resolveType(cfg.returnType) : null; - - var q = Container.createQueryable(context, es); - q.defaultType = returnType || $data.Object; - - if (returnType === $data.Queryable) { - q.defaultType = Container.resolveType(cfg.elementType); - if (clb) { - es.isTerminated = true; - return q._runQuery(clb); - } - return q; - } - es.isTerminated = true; - return q._runQuery(clb); - } - }; - }; - - var params = []; - if (cfg.params) { - for (var i = 0; i < cfg.params.length; i++) { - var param = cfg.params[i]; - for (var name in param) { - params.push({ - name: name, - type: param[name] - }); - } - } - } - $data.typeSystem.extend(fn, cfg, { params: params }); - - return fn; - }, - _convertLogicalTypeNameToPhysical: function (name) { - return name + '_$db$'; - }, - _storageModelCache: { - get: function () { - if (!this.__storageModelCache) - this.__storageModelCache = {}; - return this.__storageModelCache; - }, - set: function () { - //todo exception - } - } -}); -$data.Class.define('$data.QueryProvider', null, null, -{ - //TODO: instance member????? - constructor: function () { this.requiresExpressions= false }, - executeQuery: function (queryable, resultHandler) { - }, - getTraceString: function (queryable) { - } -}, null);$data.Class.define('$data.ModelBinder', null, null, { - - constructor: function (context) { - this.context = context; - this.providerName = null; - if (this.context.storageProvider && typeof this.context.storageProvider.getType === 'function') { - this.references = !(this.context.storageProvider.providerConfiguration.modelBinderOptimization || false); - for (var i in $data.RegisteredStorageProviders) { - if ($data.RegisteredStorageProviders[i] === this.context.storageProvider.getType()) { - this.providerName = i; - } - } - } - }, - - _deepExtend: function (o, r) { - if (o === null || o === undefined) { - return r; - } - for (var i in r) { - if (o.hasOwnProperty(i)) { - if (typeof r[i] === 'object') { - if (Array.isArray(r[i])) { - for (var j = 0; j < r[i].length; j++) { - if (o[i].indexOf(r[i][j]) < 0) { - o[i].push(r[i][j]); - } - } - } else this._deepExtend(o[i], r[i]); - } - } else { - o[i] = r[i]; - } - } - return this._finalize(o); - }, - - _finalize: function(o){ - if (o instanceof $data.Entity) { - o.changedProperties = undefined; - o.storeToken = this.context.storeToken; - } - return o; - }, - - _buildSelector: function (meta, context) { - if (meta.$selector) { - if (!(Array.isArray(meta.$selector))) { - meta.$selector = [meta.$selector]; - } - - for (var i = 0; i < meta.$selector.length; i++) { - var selector = meta.$selector[i].replace('json:', ''); - context.src += 'if('; - var path = selector.split('.'); - for (var j = 0; j < path.length; j++) { - context.src += 'di.' + path.slice(0, j + 1).join('.') + (j < path.length - 1 ? ' && ' : ' !== undefined && typeof di.' + selector + ' === "object"'); - } - context.src += '){di = di.' + selector + ';}' + (i < meta.$selector.length - 1 ? 'else ' : ''); - } - - context.src += 'if (di === null){'; - if (context.iter) context.src += context.iter + ' = null;'; - context.src += 'return null;'; - context.src += '}'; - } - }, - - _buildKey: function (name, type, keys, context, data) { - if (keys) { - var type = Container.resolveType(type); - var typeIndex = Container.getIndex(type); - type = type.fullName || type.name; - context.src += 'var ' + name + 'Fn = function(di){'; - if (!(Array.isArray(keys)) || keys.length == 1) { - if (typeof keys !== 'string') keys = keys[0]; - context.src += 'if (typeof di.' + keys + ' === "undefined") return undefined;'; - context.src += 'if (di.' + keys + ' === null) return null;'; - context.src += 'var key = ("' + type + '_' + typeIndex + '_' + keys + '#" + di.' + keys + ');'; - } else { - context.src += 'var key = "";'; - for (var i = 0; i < keys.length; i++) { - var id = typeof keys[i] !== 'object' ? keys[i] : keys[i].$source; - context.src += 'if (typeof di.' + id + ' === "undefined") return undefined;'; - context.src += 'if (di.' + id + ' === null) return null;'; - context.src += 'key += ("' + type + '_' + typeIndex + '_' + id + '#" + di.' + id + ');'; - } - } - - context.src += 'return key;};'; - } - - context.src += 'var ' + name + ' = ' + (keys ? name + 'Fn(' + (data || 'di') + ')' : 'undefined') + ';'; - }, - - build: function (meta, context) { - if (meta.$selector) { - if (!(Array.isArray(meta.$selector))) meta.$selector = [meta.$selector]; - for (var i = 0; i < meta.$selector.length; i++) { - meta.$selector[i] = meta.$selector[i].replace('json:', ''); - } - } - - if (meta.$value) { - if (typeof meta.$value === 'function') { - context.src += 'var di = di || data;'; - context.src += 'var fn = function(){ return meta' + (context.meta.length ? '.' + context.meta.join('.') : '') + '.$value.call(self, meta' + (context.meta.length ? '.' + context.meta.join('.') : '') + ', di); };'; - if (meta.$type) { - var type = Container.resolveName(Container.resolveType(meta.$type)); - var typeIndex = Container.getIndex(Container.resolveType(meta.$type)); - var converter = this.context.storageProvider.fieldConverter.fromDb[type]; - if (converter) { - context.item = 'self.context.storageProvider.fieldConverter.fromDb["' + type + '"](fn())'; - } else { - context.item = 'new (Container.resolveByIndex(' + typeIndex + '))(fn())'; - } - } else context.item = 'fn()'; - } else if (meta.$type) { - var type = Container.resolveName(Container.resolveType(meta.$type)); - var typeIndex = Container.getIndex(Container.resolveType(meta.$type)); - var converter = this.context.storageProvider.fieldConverter.fromDb[type]; - if (converter) { - context.item = 'self.context.storageProvider.fieldConverter.fromDb["' + type + '"](' + meta.$value + ')'; - } else { - context.item = 'new (Container.resolveByIndex(' + typeIndex + '))(' + meta.$value + ')'; - } - } else context.item = meta.$value; - } else if (meta.$source) { - var type = Container.resolveName(Container.resolveType(meta.$type)); - var typeIndex = Container.getIndex(Container.resolveType(meta.$type)); - var converter = this.context.storageProvider.fieldConverter.fromDb[type]; - var item = '_' + type.replace(/\./gi, '_') + '_'; - if (!context.forEach) context.src += 'var di = data;'; - context.item = item; - this._buildSelector(meta, context); - if (converter) { - context.src += 'var ' + item + ' = self.context.storageProvider.fieldConverter.fromDb["' + type + '"](di.' + meta.$source + ');'; - } else { - context.src += 'var ' + item + ' = new (Container.resolveByIndex(' + typeIndex + '))(di.' + meta.$source + ');'; - } - } else if (meta.$item) { - context.meta.push('$item'); - var iter = (context.item && context.current ? context.item + '.' + context.current : (context.item ? context.item : 'result')); - context.iter = iter; - if (iter.indexOf('.') < 0) context.src += 'var ' + iter + ';'; - context.src += 'var fn = function(di){'; - if (meta.$selector) { - context.src += 'if (typeof di !== "undefined" && !(Array.isArray(di))){'; - this._buildSelector(meta, context); - context.src += '}'; - } - if (this.references && meta.$keys) this._buildKey('forKey', meta.$type, meta.$keys, context); - //else if (this.references && meta.$item && meta.$item.$keys) this._buildKey('forKey', meta.$type, meta.$item.$keys, context); - //else context.src += 'var forKey = typeof itemKey !== "undefined" ? itemKey : undefined;'; - /*context.src += 'if (typeof forKey !== "undefined" && forKey){'; - context.src += 'if (cache[forKey]){'; - context.src += iter + ' = cache[forKey];'; - context.src += '}else{'; - context.src += iter + ' = [];'; - context.src += 'cache[forKey] = ' + iter + ';'; - context.src += '}'; - context.src += '}else{'; - context.src += iter + ' = [];'; - context.src += '}';*/ - context.src += iter + ' = typeof ' + iter + ' == "undefined" ? [] : ' + iter + ';'; - //context.src += iter + ' = [];'; - if (this.references && meta.$item.$keys) { - var keycacheName = 'keycache_' + iter.replace(/\./gi, '_'); - context.src += 'var ' + keycacheName + ';'; - context.src += 'var kci = keycacheIter.indexOf(' + iter + ');'; - context.src += 'if (kci < 0){'; - context.src += keycacheName + ' = [];'; - context.src += 'keycache.push(' + keycacheName + ');'; - context.src += 'keycacheIter.push(' + iter + ');'; - context.src += '}else{'; - context.src += keycacheName + ' = keycache[kci];'; - context.src += '}'; - //context.src += 'var ' + keycacheName + ' = ' + (meta.$item.$keys ? '[]' : 'null') + ';'; - } - context.iter = undefined; - context.forEach = true; - var itemForKey = 'itemForKey_' + iter.replace(/\./gi, '_'); - context.src += 'var forEachFn = function(di, i){'; - context.src += 'var diBackup = di;'; - if (this.providerName == "sqLite" && this.references && meta.$item.$keys) this._buildKey(itemForKey, meta.$type, meta.$item.$keys, context); - var item = context.item || 'iter'; - context.item = item; - if (!meta.$item.$source) { - this._buildSelector(meta.$item, context); - } - this.build(meta.$item, context); - if (this.references && meta.$keys) { - context.src += 'if (forKey){'; - context.src += 'if (cache[forKey]){'; - context.src += iter + ' = cache[forKey];'; - context.src += 'if (' + iter + '.indexOf(' + (context.item || item) + ') < 0){'; - context.src += iter + '.push(' + (context.item || item) + ');'; - context.src += '}}else{'; - context.src += 'cache[forKey] = ' + iter + ';'; - context.src += iter + '.push(' + (context.item || item) + ');'; - context.src += '}}else{'; - if (this.references && meta.$item.$keys) this._buildKey('cacheKey', meta.$type, meta.$item.$keys, context, 'diBackup'); - context.src += 'if (typeof cacheKey != "undefined" && cacheKey !== null){'; - context.src += 'if (keycache_' + iter.replace(/\./gi, '_') + ' && cacheKey){'; - context.src += 'if (keycache_' + iter.replace(/\./gi, '_') + '.indexOf(cacheKey) < 0){'; - context.src += iter + '.push(' + (context.item || item) + ');'; - context.src += 'keycache_' + iter.replace(/\./gi, '_') + '.push(cacheKey);'; - context.src += '}'; - context.src += '}else{'; - context.src += iter + '.push(' + (context.item || item) + ');'; - context.src += '}'; - context.src += '}'; - context.src += '}'; - } else { - if (this.references && meta.$item.$keys) { - context.src += 'if (typeof ' + itemForKey + ' !== "undefined" && ' + itemForKey + ' !== null){'; - context.src += 'if (typeof keycache_' + iter.replace(/\./gi, '_') + ' !== "undefined" && ' + itemForKey + '){'; - context.src += 'if (keycache_' + iter.replace(/\./gi, '_') + '.indexOf(' + itemForKey + ') < 0){'; - context.src += iter + '.push(' + (context.item || item) + ');'; - context.src += 'keycache_' + iter.replace(/\./gi, '_') + '.push(' + itemForKey + ');' - context.src += '}}else{'; - context.src += iter + '.push(' + (context.item || item) + ');'; - context.src += '}}else{'; - context.src += iter + '.push(' + (context.item || item) + ');'; - context.src += '}'; - /*context.src += 'if (typeof itemKey !== "undefined" && itemKey !== null){'; - context.src += 'if (typeof keycache_' + iter.replace(/\./gi, '_') + ' !== "undefined" && itemKey){'; - context.src += 'if (keycache_' + iter.replace(/\./gi, '_') + '.indexOf(itemKey) < 0){'; - context.src += iter + '.push(' + (context.item || item) + ');'; - context.src += 'keycache_' + iter.replace(/\./gi, '_') + '.push(itemKey);' - context.src += '}}else{'; - context.src += iter + '.push(' + (context.item || item) + ');'; - context.src += '}}else{'; - context.src += iter + '.push(' + (context.item || item) + ');'; - context.src += '}';*/ - } else { - context.src += iter + '.push(' + (context.item || item) + ');'; - } - } - context.src += '};'; - context.src += 'if (Array.isArray(di)) di.forEach(forEachFn);'; - context.src += 'else forEachFn(di, 0);'; - context.forEach = false; - context.item = null; - context.src += '};fn(typeof di === "undefined" ? data : di);' - context.meta.pop(); - } else if (meta.$type) { - if (!context.forEach) { - context.src += 'if (typeof di === "undefined"){'; - context.src += 'var di = data;'; - this._buildSelector(meta, context); - context.src += '}'; - } - var resolvedType = Container.resolveType(meta.$type); - var type = Container.resolveName(resolvedType); - var typeIndex = Container.getIndex(resolvedType); - var isEntityType = resolvedType.isAssignableTo && resolvedType.isAssignableTo($data.Entity); - var item = '_' + type.replace(/\./gi, '_') + '_'; - if (context.item == item) item += 'new_'; - context.item = item; - - - var isPrimitive = false; - if (!meta.$source && !meta.$value && resolvedType !== $data.Array && resolvedType !== $data.Object && !resolvedType.isAssignableTo) - isPrimitive = true; - if (resolvedType === $data.Object || resolvedType === $data.Array) { - var keys = Object.keys(meta); - if (keys.length == 1 || (keys.length == 2 && meta.$selector)) isPrimitive = true; - } - - if (isPrimitive) { - var converter = this.context.storageProvider.fieldConverter.fromDb[type]; - if (converter) { - context.src += 'var ' + item + ' = di != undefined ? self.context.storageProvider.fieldConverter.fromDb["' + type + '"](di) : di;'; - } else { - context.src += 'var ' + item + ' = di;'; - } - } else { - if (this.references && meta.$keys) { - this._buildKey('itemKey', meta.$type, meta.$keys, context); - context.src += 'if (itemKey === null) return null;'; - context.src += 'var ' + item + ';'; - context.src += 'if (itemKey && cache[itemKey]){'; - context.src += item + ' = cache[itemKey];'; - context.src += '}else{'; - if (isEntityType) { - context.src += item + ' = new (Container.resolveByIndex(' + typeIndex + '))(undefined, { setDefaultValues: false });'; - } else { - context.src += item + ' = new (Container.resolveByIndex(' + typeIndex + '))();'; - } - context.src += 'if (itemKey){'; - context.src += 'cache[itemKey] = ' + item + ';'; - context.src += '}'; - context.src += '}'; - } else { - if (isEntityType) { - context.src += 'var ' + item + ' = new (Container.resolveByIndex(' + typeIndex + '))(undefined, { setDefaultValues: false });'; - } else { - context.src += 'var ' + item + ' = new (Container.resolveByIndex(' + typeIndex + '))();'; - } - } - } - for (var i in meta) { - if (i.indexOf('$') < 0) { - context.current = i; - if (!meta[i].$item) { - if (meta[i].$value) { - context.meta.push(i); - var item = context.item; - this.build(meta[i], context); - context.src += item + '.' + i + ' = ' + context.item + ';'; - context.item = item; - context.meta.pop(); - } else if (meta[i].$source) { - context.src += 'var fn = function(di){'; - this._buildSelector(meta[i], context); - if (meta[i].$type) { - var type = Container.resolveName(Container.resolveType(meta[i].$type)); - var typeIndex = Container.getIndex(Container.resolveType(meta[i].$type)); - var converter = this.context.storageProvider.fieldConverter.fromDb[type]; - if (converter) { - context.src += 'return self.context.storageProvider.fieldConverter.fromDb["' + type + '"](di.' + meta[i].$source + ');'; - } else { - context.src += 'return new (Container.resolveByIndex(' + typeIndex + '))(di.' + meta[i].$source + ');'; - } - } else { - context.src += item + '.' + i + ' = di.' + meta[i].$source + ';'; - } - context.src += '};'; - if (meta[i].$type) context.src += item + '.' + i + ' = fn(di);'; - else context.src += 'fn(di);'; - } else if (meta[i].$type) { - context.meta.push(i); - context.src += 'var fn = function(di){'; - this._buildSelector(meta[i], context); - this.build(meta[i], context); - context.src += 'return ' + context.item + ';};'; - if (meta[i].$type === $data.Object) context.src += item + '.' + i + ' = self._deepExtend(' + item + '.' + i + ', fn(di));'; - else context.src += item + '.' + i + ' = fn(di);'; - context.item = item; - context.meta.pop(); - } else if (meta.$type) { - var memDef = Container.resolveType(meta.$type).memberDefinitions.getMember(i); - var type = Container.resolveName(memDef.type); - var entityType = Container.resolveType(meta.$type); - var entityTypeIndex = Container.getIndex(meta.$type); - var converter = this.context.storageProvider.fieldConverter.fromDb[type]; - if (this.providerName && memDef && memDef.converter && memDef.converter[this.providerName] && typeof memDef.converter[this.providerName].fromDb == 'function') { - context.src += item + '.' + i + ' = Container.resolveByIndex("' + entityTypeIndex + '").memberDefinitions.getMember("' + i + '").converter.' + this.providerName + '.fromDb(di.' + meta[i] + ', Container.resolveByIndex("' + entityTypeIndex + '").memberDefinitions.getMember("' + i + '"), self.context, Container.resolveByIndex("' + entityTypeIndex + '"));'; - } else if (converter) { - context.src += item + '.' + i + ' = self.context.storageProvider.fieldConverter.fromDb["' + type + '"](di.' + meta[i] + ');'; - } else { - //var type = Container.resolveName(Container.resolveType(type.memberDefinitions.getMember(i).type)); - var typeIndex = Container.getIndex(Container.resolveType(type.memberDefinitions.getMember(i).type)); - context.src += item + '.' + i + ' = new (Container.resolveByIndex(' + typeIndex + '))(di.' + meta[i] + ');'; - } - } - } else { - context.meta.push(i); - this.build(meta[i], context); - context.item = item; - context.meta.pop(); - } - } - } - context.src += item + ' = self._finalize(' + item + ');'; - } - }, - - call: function (data, meta) { - if (!Object.getOwnPropertyNames(meta).length) { - return data; - } - var context = { - src: '', - meta: [] - }; - context.src += 'var self = this;'; - context.src += 'var result;'; - context.src += 'var cache = {};'; - context.src += 'var keycache = [];'; - context.src += 'var keycacheIter = [];'; - this.build(meta, context); - if (context.item) context.src += 'if (typeof result === "undefined") result = ' + context.item + ';'; - context.src += 'return result;'; - - /*var beautify = require('beautifyjs'); - console.log(beautify.js_beautify(context.src));*/ - - var fn = new Function('meta', 'data', context.src).bind(this); - var ret = fn(meta, data); - return ret; - } -}); -$C('$data.queryBuilder', null, null, { - constructor: function () { - this._fragments = {}; - this.selectedFragment = null; - this._binderConfig = {}; - this.modelBinderConfig = this._binderConfig; - this._binderConfigPropertyStack = []; - }, - selectTextPart: function (name) { - if (!this._fragments[name]) { - this._fragments[name] = { text: '', params: [] }; - } - this.selectedFragment = this._fragments[name]; - }, - getTextPart: function (name) { - return this._fragments[name]; - }, - addText: function (textParticle) { - this.selectedFragment.text += textParticle; - }, - addParameter: function (param) { - this.selectedFragment.params.push(param); - }, - selectModelBinderProperty: function (name) { - this._binderConfigPropertyStack.push(this.modelBinderConfig); - if (!(name in this.modelBinderConfig)) { - this.modelBinderConfig[name] = {}; - } - this.modelBinderConfig = this.modelBinderConfig[name]; - }, - popModelBinderProperty: function () { - if (this._binderConfigPropertyStack.length === 0) { - this.modelBinderConfig = this._binderConfig(); - } else { - this.modelBinderConfig = this._binderConfigPropertyStack.pop(); - } - }, - resetModelBinderProperty: function (name) { - this._binderConfigPropertyStack = []; - this.modelBinderConfig = this._binderConfig; - }, - addKeyField: function (name) { - if(!this.modelBinderConfig['$keys']){ - this.modelBinderConfig['$keys'] = new Array(); - } - this.modelBinderConfig['$keys'].push(name); - } -}); -$C('$data.Query', null, null, -{ - constructor: function (expression, defaultType, context) { - /// - /// - /// - - this.expression = expression; - this.context = context; - - //TODO: expressions get as JSON string?! - - this.expressions = expression; - this.defaultType = defaultType; - this.result = []; - this.rawDataList = []; - this.modelBinderConfig = {}; - this.context = context; - }, - - rawDataList: { dataType: "Array" }, - result: { dataType: "Array" }, - resultType: {}, - buildResultSet: function (ctx) { - var converter = new $data.ModelBinder(this.context); - this.result = converter.call(this.rawDataList, this.modelBinderConfig); - return; - }, - getEntitySets: function(){ - var ret = []; - var ctx = this.context; - - var fn = function(expression){ - if (expression instanceof $data.Expressions.EntitySetExpression){ - if (ret.indexOf(ctx._entitySetReferences[expression.elementType.name]) < 0) - ret.push(ctx._entitySetReferences[expression.elementType.name]); - } - if (expression.source) fn(expression.source); - }; - - fn(this.expression); - - return ret; - } -}, null); -$data.Class.define('$data.Queryable', null, null, -{ - constructor: function (source, rootExpression) { - /// - /// Provides a base class for classes supporting JavaScript Language Query. - /// Provides a base class for classes supporting JavaScript Language Query. - /// - /// - /// - /// - /// Provides a base class for classes supporting JavaScript Language Query. - /// Provides a base class for classes supporting JavaScript Language Query. - /// - /// - /// - - var context = source instanceof $data.EntityContext ? source : source.entityContext; - this.defaultType = source instanceof $data.EntityContext ? null : source.defaultType; - this.entityContext = context; - this.expression = rootExpression; - }, - - filter: function (predicate, thisArg) { - ///Filters a set of entities using a boolean expression. - ///A boolean query expression - ///The query parameters - /// - /// - ///Filters a set of entities using a boolean expression formulated as string. - /// - ///The expression body of the predicate function in string. - ///To reference the lambda parameter use the 'it' context variable. - ///Example: filter("it.Title == 'Hello'") - /// - /// - /// - /// - /// - ///Filters a set of entities using a bool expression formulated as a JavaScript function. - /// - /// - /// - ///Contains the predicate parameters - /// - /// - /// - ///Filtering a set of entities with a predicate function - ///var males = Persons.filter( function( person ) { return person.Gender == 'Male' } ); - /// - /// - ///Filtering a set of entities with a predicate function and parameters - ///var draftables = Persons.filter( function( person ) { - /// return person.Gender == this.gender && person.Age > this.age - /// }, { gender: 'Male', age: 21 }); - /// - /// - ///Filtering a set of entities with a predicate as a string and parameters - ///var draftables = Persons.filter("it.Gender == this.gender && it.Age > this.age", - /// { gender: 'Male', age: 21 }); - /// - /// - if (arguments.length === 3) { - predicate = "it." + arguments[0] + - (arguments[1][0] === "." ? (arguments[1] + "(param)") : (" " + arguments[1] + " param")); - thisArg = { param : arguments[2] } - } - this._checkOperation('filter'); - var expression = Container.createCodeExpression(predicate, thisArg); - var expressionSource = this.expression; - if (this.expression instanceof $data.Expressions.FilterExpression) { - expressionSource = this.expression.source; - - var operatorResolution = this.entityContext.storageProvider.resolveBinaryOperator("and"); - expression = Container.createSimpleBinaryExpression(this.expression.selector, expression, "and", "filter", "boolean", operatorResolution); - } - var exp = Container.createFilterExpression(expressionSource, expression); - var q = Container.createQueryable(this, exp); - return q; - }, - where: function (predicate, params) { - ///Where is a convenience alias for C# developers. Use filter instead. - /// - return this.filter(predicate, params); - }, - - map: function (projection, thisArg, mappedTo) { - /// Map specifies the shape or type of each returned element. You can specify whether your results will consist of complete Person objects, just one member, a subset of members, or some completely different result type based on a computation or new object creation. When map produces something other than a copy of the source element, the operation is called a projection. The use of projections to transform data is a powerful capability of JavaScript Language Query expressions. - /// A projection expression - /// The query parameters - /// - /// - /// Map specifies the shape or type of each returned element. You can specify whether your results will consist of complete Person objects, just one member, a subset of members, or some completely different result type based on a computation or new object creation. When map produces something other than a copy of the source element, the operation is called a projection. The use of projections to transform data is a powerful capability of JavaScript Language Query expressions. - /// - /// The expression body of the projection function in string. - /// To reference the lambda parameter use the 'it' context variable. - /// Example: map("{ i: it.Id, t: it.Title }") - /// - /// - /// - /// - /// - /// Map specifies the shape or type of each returned element. You can specify whether your results will consist of complete Person objects, just one member, a subset of members, or some completely different result type based on a computation or new object creation. When map produces something other than a copy of the source element, the operation is called a projection. The use of projections to transform data is a powerful capability of JavaScript Language Query expressions. - /// - /// Projection function to specify the shape or type of each returned element. - /// - /// - /// Contains the projection parameters. - /// - /// - /// - /// Projection to get an array of the full name property of a set of Person entities - /// var personFullNames = Persons.map( function( person ) { return person.FullName; } ); - /// - /// - /// Projection to get an array of the required fields of Person entities in an anonymous type. - /// var custom = Persons.map( function( person ) { - /// return { FullName: person.FullName, Info: { Address: person.Location.Address, Phone: person.Phone } }; - /// }); - /// - /// - - this._checkOperation('map'); - var codeExpression = Container.createCodeExpression(projection, thisArg); - var exp = Container.createProjectionExpression(this.expression, codeExpression); - - if (mappedTo === 'default') - exp.projectionAs = this.defaultType; - else if (mappedTo) - exp.projectionAs = Container.resolveType(mappedTo); - else - exp.projectionAs = $data.Object; - - var q = Container.createQueryable(this, exp); - return q; - }, - select: function (projection, thisArg, mappedTo) { - ///Select is a convenience alias for C# developers. Use map instead. - /// - return this.map(projection, thisArg, mappedTo); - }, - - length: function (onResult, transaction) { - /// Returns the number of entities (or projected object) in a query as the callback parameter. - /// A callback function - /// - /// - /// Returns the number of entities (or projected object) in a query as the callback parameter. - /// - /// The callback function to handle the result. - /// - /// - /// - /// - /// Returns the number of entities (or projected object) in a query as the callback parameter. - /// - /// Object of callback functions to handle success and error. - /// Example: { success: function(cnt) { ... }, error: function() { alert("Something went wrong..."); } } - /// - /// - /// - /// Get the count of Person entities. - /// Persons.length( function( cnt ) { alert("There are " + cnt + " person(s) in the database."); } ); - /// - /// - - this._checkOperation('length'); - var pHandler = new $data.PromiseHandler(); - var cbWrapper = pHandler.createCallback(onResult); - - var countExpression = Container.createCountExpression(this.expression); - var preparator = Container.createQueryExpressionCreator(this.entityContext); - try { - var expression = preparator.Visit(countExpression); - this.entityContext.log({ event: "EntityExpression", data: expression }); - - this.entityContext.executeQuery(Container.createQueryable(this, expression), cbWrapper, transaction); - } catch (e) { - cbWrapper.error(e); - } - - return pHandler.getPromise(); - }, - count: function (onResult, transaction) { - ///Count is a convenience alias for C# developers. Use length instead. - /// - return this.length(onResult, transaction); - }, - - forEach: function (iterator, transaction) { - /// Calls the iterator function for all entity (or projected object) in the query. - /// Iterator function - /// - /// - /// Calls the iterator function for all entity (or projected object) in the query. - /// - /// Iterator function to handle the result elements. - /// - /// - /// - /// Log the full name of each Person. - /// Persons.forEach( function( person ) { console.log(person.FullName; } ); - /// - /// - - this._checkOperation('forEach'); - var pHandler = new $data.PromiseHandler(); - function iteratorFunc(items) { items.forEach(iterator); } - var cbWrapper = pHandler.createCallback(iteratorFunc); - - var forEachExpression = Container.createForEachExpression(this.expression); - var preparator = Container.createQueryExpressionCreator(this.entityContext); - try { - var expression = preparator.Visit(forEachExpression); - this.entityContext.log({ event: "EntityExpression", data: expression }); - - this.entityContext.executeQuery(Container.createQueryable(this, expression), cbWrapper, transaction); - } catch (e) { - cbWrapper.error(e); - } - - return pHandler.getPromise(); - }, - - toArray: function (onResult_items, transaction) { - /// Returns the query result as the callback parameter. - /// A callback function - /// - /// - /// Returns the query result as the callback parameter. - /// - /// The callback function to handle the result. - /// - /// - /// - /// - /// Returns the query result as the callback parameter. - /// - /// Object of callback functions to handle success and error. - /// Example: { success: function(result) { ... }, error: function() { alert("Something went wrong..."); } } - /// - /// - /// - /// Get all Person entities. - /// Persons.toArray( function( result ) { console.dir(result); } ); - /// - /// - - if (onResult_items instanceof $data.Array) - { - return this.toArray(function (results) { - onResult_items.length = 0; - results.forEach(function (item, idx) { - onResult_items.push(item); - }); - }); - } - - this._checkOperation('toArray'); - var pHandler = new $data.PromiseHandler(); - var cbWrapper = pHandler.createCallback(onResult_items); - - var toArrayExpression = Container.createToArrayExpression(this.expression); - var preparator = Container.createQueryExpressionCreator(this.entityContext); - try { - var expression = preparator.Visit(toArrayExpression); - this.entityContext.log({ event: "EntityExpression", data: expression }); - - this.entityContext.executeQuery(Container.createQueryable(this, expression), cbWrapper, transaction); - } catch (e) { - cbWrapper.error(e); - } - - return pHandler.getPromise(); - }, - toLiveArray: function (onResult, transaction) { - var self = this; - var result = []; - - var doAction = function (action) { - return function (onResult) { - var pHandler = new $data.PromiseHandler(); - var callback = pHandler.createCallback(onResult); - - var successFunc = function (res) { - result.length = 0; - - var data = res; - $data.typeSystem.extend(result, data); - - result.prev = doAction(function (cb) { - data.prev(cb); - }); - result.next = doAction(function (cb) { - data.next(cb); - }); - - callback.success.apply(this, [result].concat(Array.prototype.slice.call(arguments, 1))); - } - - action({ - success: successFunc, - error: callback.error - }, transaction); - - var promise = pHandler.getPromise(); - $data.typeSystem.extend(result, promise); - - return result; - } - } - - result.refresh = doAction(function (cb) { - self.toArray(cb); - }); - - return result.refresh.apply(result, arguments); - }, - - single: function (filterPredicate, thisArg, onResult, transaction) { - /// Filters a set of entities using a boolean expression and returns a single element or throws an error if more than one element is filtered. - /// A callback function - /// - /// - /// Filters a set of entities using a boolean expression and returns a single element or throws an error if more than one element is filtered. - /// - /// Same as in filter. - /// - /// - /// The callback function to handle the result, same as in toArray. - /// - /// - /// - /// - /// Filters a set of entities using a boolean expression and returns a single element or throws an error if more than one element is filtered. - /// - /// Same as in filter. - /// - /// - /// The callback function to handle the result, same as in toArray. - /// - /// - /// - /// Get "George" from the Person entity set. - /// Persons.single( function( person ) { return person.FirstName == this.name; }, { name: "George" }, { - /// success: function ( result ){ ... }, - /// error: function () { ... } - /// }); - /// - /// - - this._checkOperation('single'); - var q = this; - if (filterPredicate) { - q = this.filter(filterPredicate, thisArg); - } - q = q.take(2); - - var pHandler = new $data.PromiseHandler(); - var cbWrapper = pHandler.createCallback(onResult); - - var singleExpression = Container.createSingleExpression(q.expression); - var preparator = Container.createQueryExpressionCreator(q.entityContext); - try { - var expression = preparator.Visit(singleExpression); - this.entityContext.log({ event: "EntityExpression", data: expression }); - - q.entityContext.executeQuery(Container.createQueryable(q, expression), cbWrapper, transaction); - } catch (e) { - cbWrapper.error(e); - } - - return pHandler.getPromise(); - }, - - some: function (filterPredicate, thisArg, onResult, transaction) { - /// Filters a set of entities using a boolean expression and returns true if the query has any result element. - /// Filter function - /// The query parameters for filter function - /// A callback function - /// - /// - /// Filters a set of entities using a boolean expression and returns true if the query has any result element. - /// - /// Same as in filter. - /// - /// - /// The callback function to handle the result, same as in toArray. - /// - /// - /// - /// - /// Filters a set of entities using a boolean expression and returns true if the query has any result element. - /// - /// Same as in filter. - /// - /// - /// The callback function to handle the result, same as in toArray. - /// - /// - /// - /// Is there any person who's first name is "George"? - /// Persons.some( function( person ) { return person.FirstName == this.name; }, { name: "George" }, { - /// success: function ( result ){ ... }, - /// error: function () { ... } - /// }); - /// - /// - - this._checkOperation('some'); - var q = this; - if (filterPredicate) { - q = this.filter(filterPredicate, thisArg); - } - q = q.take(1); - - var pHandler = new $data.PromiseHandler(); - var cbWrapper = pHandler.createCallback(onResult); - - var someExpression = Container.createSomeExpression(q.expression); - var preparator = Container.createQueryExpressionCreator(q.entityContext); - try { - var expression = preparator.Visit(someExpression); - this.entityContext.log({ event: "EntityExpression", data: expression }); - - q.entityContext.executeQuery(Container.createQueryable(q, expression), cbWrapper, transaction); - } catch (e) { - cbWrapper.error(e); - } - - return pHandler.getPromise(); - }, - - every: function (filterPredicate, thisArg, onResult, transaction) { - /// Filters a set of entities using a boolean expression and returns true if all elements of the EntitySet is in the result set. - /// Filter function - /// The query parameters for filter function - /// A callback function - /// - /// - /// Filters a set of entities using a boolean expression and returns a - /// - /// Same as in filter. - /// - /// - /// The callback function to handle the result, same as in toArray. - /// - /// - /// - /// - /// Filters a set of entities using a boolean expression and returns a single element or throws an error if more than one element is filtered. - /// - /// Same as in filter. - /// - /// - /// The callback function to handle the result, same as in toArray. - /// - /// - /// - /// Result is true when all person are married. - /// Persons.every( function( person ) { return person.Married == true; }, null, { - /// success: function ( result ){ ... }, - /// error: function () { ... } - /// }); - /// - /// - - this._checkOperation('every'); - var q = this; - if (filterPredicate) { - q = this.filter(filterPredicate, thisArg); - } - q = q.take(1); - - var pHandler = new $data.PromiseHandler(); - var cbWrapper = pHandler.createCallback(onResult); - - var everyExpression = Container.createEveryExpression(q.expression); - var preparator = Container.createQueryExpressionCreator(q.entityContext); - try { - var expression = preparator.Visit(everyExpression); - this.entityContext.log({ event: "EntityExpression", data: expression }); - - q.entityContext.executeQuery(Container.createQueryable(q, expression), cbWrapper, transaction); - } catch (e) { - cbWrapper.error(e); - } - - return pHandler.getPromise(); - }, - - - take: function (amount) { - /// Returns only a specified number of elements from the start of the result set. - /// The number of elements to return. - /// - /// - /// Returns only a specified number of elements from the start of the result set. - /// - /// The number of elements to skip. - /// - /// - /// - /// Log the full name of each Person. - /// Persons.take(10).forEach( function( person ) { console.log(person.FullName; } ); - /// - /// - - this._checkOperation('take'); - var constExp = Container.createConstantExpression(amount, "number"); - var takeExp = Container.createPagingExpression(this.expression, constExp, $data.Expressions.ExpressionType.Take); - return Container.createQueryable(this, takeExp); - }, - skip: function (amount) { - /// Skip a specified number of elements from the start of the result set. - /// The number of elements to skip. - /// - /// - /// Skip a specified number of elements from the start of the result set. - /// - /// The number of elements to skip. - /// - /// - /// - /// Log the full name of each Person. - /// Persons.skip(1).take(5).forEach( function( person ) { console.log(person.FullName; } ); - /// - /// - - this._checkOperation('skip'); - var constExp = Container.createConstantExpression(amount, "number"); - var takeExp = Container.createPagingExpression(this.expression, constExp, $data.Expressions.ExpressionType.Skip); - return Container.createQueryable(this, takeExp); - }, - - order: function(selector) { - if (selector === '' || selector === undefined || selector === null) { - return this; - } - if(selector[0] === "-") { - var orderString = "it." + selector.replace("-",""); - return this.orderByDescending(orderString); - } else { - return this.orderBy("it." + selector); - } - - }, - - orderBy: function (selector, thisArg) { - ///Order a set of entities using an expression. - ///An order expression - ///The query parameters - /// - /// - ///Order a set of entities using an expression. - /// - ///The expression body of the order function in string. - ///To reference the lambda parameter use the 'it' context variable. - ///Example: orderBy("it.Id") - /// - /// - /// - /// - /// - ///Order a set of entities using an expression. - /// - /// - /// - ///Contains the predicate parameters - /// - /// - /// - ///Ordering a set of entities with a predicate function - ///var males = Persons.orderBy( function( person ) { return person.Id; } ); - /// - /// - - this._checkOperation('orderBy'); - var codeExpression = Container.createCodeExpression(selector, thisArg); - var exp = Container.createOrderExpression(this.expression, codeExpression, $data.Expressions.ExpressionType.OrderBy); - var q = Container.createQueryable(this, exp); - return q; - }, - orderByDescending: function (selector, thisArg) { - ///Order a set of entities descending using an expression. - ///An order expression - ///The query parameters - /// - /// - ///Order a set of entities descending using an expression. - /// - ///The expression body of the order function in string. - ///To reference the lambda parameter use the 'it' context variable. - ///Example: orderBy("it.Id") - /// - /// - /// - /// - /// - ///Order a set of entities descending using an expression. - /// - /// - /// - ///Contains the predicate parameters - /// - /// - /// - ///Ordering a set of entities with a predicate function - ///var males = Persons.orderByDescending( function( person ) { return person.Id; } ); - /// - /// - - this._checkOperation('orderByDescending'); - var codeExpression = Container.createCodeExpression(selector, thisArg); - var exp = Container.createOrderExpression(this.expression, codeExpression, $data.Expressions.ExpressionType.OrderByDescending); - var q = Container.createQueryable(this, exp); - return q; - }, - - first: function (filterPredicate, thisArg, onResult, transaction) { - /// Filters a set of entities using a boolean expression and returns the first element. - /// A callback function - /// - /// - /// Filters a set of entities using a boolean expression and returns the first element. - /// - /// Same as in filter. - /// - /// - /// The callback function to handle the result, same as in toArray. - /// - /// - /// - /// - /// Filters a set of entities using a boolean expression and returns the first element. - /// - /// Same as in filter. - /// - /// - /// The callback function to handle the result, same as in toArray. - /// - /// - /// - /// Get "George" from the Person entity set. - /// Persons.first( function( person ) { return person.FirstName == this.name; }, { name: "George" }, function ( result ){ ... }); - /// - /// - - this._checkOperation('first'); - var q = this; - if (filterPredicate) { - q = this.filter(filterPredicate, thisArg); - } - q = q.take(1); - - var pHandler = new $data.PromiseHandler(); - var cbWrapper = pHandler.createCallback(onResult); - - var firstExpression = Container.createFirstExpression(q.expression); - var preparator = Container.createQueryExpressionCreator(q.entityContext); - try { - var expression = preparator.Visit(firstExpression); - q.entityContext.log({ event: "EntityExpression", data: expression }); - - q.entityContext.executeQuery(Container.createQueryable(q, expression), cbWrapper, transaction); - } catch (e) { - cbWrapper.error(e); - } - - return pHandler.getPromise(); - }, - - find: function (keyValue, onResult, transaction) { - - var pHandler = new $data.PromiseHandler(); - var cbWrapper = pHandler.createCallback(onResult); - - var keys = this.defaultType.memberDefinitions.getKeyProperties(); - - try { - - if (keys.length === 1 && typeof keyValue !== 'object') { - var keyV = {}; - keyV[keys[0].name] = keyValue; - keyValue = keyV; - } - - if (typeof keyValue !== 'object') { - throw new Exception('Key parameter is invalid'); - } else { - - - var parameters = []; - for (var i = 0; i < keys.length; i++) { - var keyProp = keys[i]; - if (!(keyProp.name in keyValue)) { - throw new Exception('Key value missing'); - } - parameters.push(Container.createConstantExpression(keyValue[keyProp.name], keyProp.type, keyProp.name)); - } - - var operation = this.entityContext.storageProvider.supportedSetOperations['find']; - if (operation) { - - var findExpression = Container.createFindExpression(this.expression, parameters); - var preparator = Container.createQueryExpressionCreator(this.entityContext); - try { - var expression = preparator.Visit(findExpression); - this.entityContext.log({ event: "EntityExpression", data: expression }); - - this.entityContext.executeQuery(Container.createQueryable(this, expression), cbWrapper, transaction); - } catch (e) { - cbWrapper.error(e); - } - - } else { - var predicate = ''; - var params = {} - for (var i = 0; i < parameters.length; i++) { - var param = parameters[i]; - params[param.name] = param.value; - if (i > 0) predicate += ' && '; - predicate += "it." + param.name + " == this." + param.name; - } - - this.single(predicate, params, cbWrapper, transaction); - } - } - } catch (e) { - cbWrapper.error(e); - } - - return pHandler.getPromise(); - }, - - include: function (selector) { - /// Includes the given entity set in the query if it's an inverse property. - /// Entity set name - /// - /// - /// Includes the given entity set in the query if it's an inverse property. - /// - /// The name of the entity set you want to include in the query. - /// - /// - /// - /// Include the Category on every Article. - /// Articles.include("Category"); - /// - /// - - this._checkOperation('include'); - var constExp = Container.createConstantExpression(selector, "string"); - var takeExp = Container.createIncludeExpression(this.expression, constExp); - return Container.createQueryable(this, takeExp); - }, - - withInlineCount: function (selector) { - this._checkOperation('withInlineCount'); - var constExp = Container.createConstantExpression(selector || 'allpages', "string"); - var inlineCountExp = Container.createInlineCountExpression(this.expression, constExp); - return Container.createQueryable(this, inlineCountExp); - }, - - removeAll: function (onResult, transaction) { - /// Delete the query result and returns the number of deleted entities in a query as the callback parameter. - /// A callback function - /// - /// - /// Delete the query result and returns the number of deleted entities in a query as the callback parameter. - /// - /// The callback function to handle the result. - /// - /// - /// - /// - /// Delete the query result and returns the number of deleted entities in a query as the callback parameter. - /// - /// Object of callback functions to handle success and error. - /// Example: { success: function(result) { ... }, error: function() { alert("Something went wrong..."); } } - /// - /// - /// - /// Delete all People who are younger than 18 years old. - /// Persons.filter( function( p ){ return p.Age < 18; } ).removeAll( function( result ) { console.dir(result); } ); - /// - /// - - this._checkOperation('batchDelete'); - var pHandler = new $data.PromiseHandler(); - var cbWrapper = pHandler.createCallback(onResult); - - var batchDeleteExpression = Container.createBatchDeleteExpression(this.expression); - var preparator = Container.createQueryExpressionCreator(this.entityContext); - try { - var expression = preparator.Visit(batchDeleteExpression); - this.entityContext.log({ event: "EntityExpression", data: expression }); - - this.entityContext.executeQuery(Container.createQueryable(this, expression), cbWrapper, transaction); - } catch (e) { - cbWrapper.error(e); - } - - return pHandler.getPromise(); - }, - - - _runQuery: function (onResult_items, transaction) { - var pHandler = new $data.PromiseHandler(); - var cbWrapper = pHandler.createCallback(onResult_items); - - var preparator = Container.createQueryExpressionCreator(this.entityContext); - try { - var expression = preparator.Visit(this.expression); - this.entityContext.log({ event: "EntityExpression", data: expression }); - - this.entityContext.executeQuery(Container.createQueryable(this, expression), cbWrapper, transaction); - } catch (e) { - cbWrapper.error(e); - } - - return pHandler.getPromise(); - }, - - toTraceString: function (name) { - /// Returns the trace string of the query. - /// Name of the execution method (toArray, length, etc.). - /// - /// - /// Returns the trace string of the query. - /// - /// Name of the execution method (toArray, length, etc.). Optional. Default value is "toArray". - /// - /// - /// - /// Get the trace string for Articles.toArray() - /// Articles.toTraceString(); - /// - /// - - var expression = this.expression; - - if (name) { - expression = Container['create' + name + 'Expression'](expression); - } else { - expression = Container.createToArrayExpression(expression); - } - - var preparator = Container.createQueryExpressionCreator(this.entityContext); - expression = preparator.Visit(expression); - - //this.expression = expression; - var q = Container.createQueryable(this, expression) - return q.entityContext.getTraceString(q); - }, - - _checkOperation: function (name) { - var operation = this.entityContext.resolveSetOperations(name); - if (operation.invokable != undefined && !operation.invokable) - Guard.raise(new Exception("Operation '" + name + "' is not invokable with the provider")); - }, - defaultType: {} - -}, null); -///EntitySet is responsible for -/// -creating and holding entityType through schema -/// - provide Add method -/// - provide Delete method -/// - provide Update method -/// - provide queryProvider for queryable - -$data.EntitySchemaConfig = function EntitySchemaConfig() { - this.Name = ""; -}; -$data.entitySetState = { created: 0, defined: 1, active: 2 }; - -$data.Class.defineEx('$data.EntitySet', - [ - { type: $data.Queryable, params: [new ConstructorParameter(1)] } - ], null, -{ - constructor: function (elementType, context, collectionName, eventHandlers, roles) { - /// - /// Represents a typed entity set that is used to perform create, read, update, and delete operations - /// Type of entity set elements, elementType must be subclass of $data.Entity - /// Context of the EntitySet - /// Name of the EntitySet - /// - this.createNew = this[elementType.name] = this.elementType = this.defaultType = elementType; - var self = this; - context['createAdd' + elementType.name] = function (initData) { - var entity = new elementType(initData); - return self.add(entity); - } - this.stateManager = new $data.EntityStateManager(this); - - this.collectionName = collectionName; - this.roles = roles; - - for (var i in eventHandlers){ - this[i] = eventHandlers[i]; - } - }, - - addNew: function(item, cb) { - var callback = $data.typeSystem.createCallbackSetting(cb); - var _item = new this.createNew(item); - this.entityContext.saveChanges(cb); - return _item; - }, - - executeQuery: function (expression, on_ready) { - //var compiledQuery = this.entityContext - var callBack = $data.typeSystem.createCallbackSetting(on_ready); - this.entityContext.executeQuery(expression, callBack); - }, - getTraceString: function (expression) { - return this.entityContext.getTraceString(expression); - }, - setContext: function (entityContext) { - this.entitySetState = $data.entitySetState.active; - this.entityContext = entityContext; - this.entityContext[this.schema.name] = this[this.schema.name]; - }, - _trackEntity: function (entity) { - var trackedEntities = this.entityContext.stateManager.trackedEntities; - for (var i = 0; i < trackedEntities.length; i++) { - if (trackedEntities[i].data === entity) - return; - } - trackedEntities.push({ entitySet: this, data: entity }); - }, - add: function (entity) { - /// - /// Creates a typed entity and adds to the context. - /// The init parameters whish is based on Entity - /// - /// - /// Persons.add({ Name: 'John', Email: 'john@example.com', Age: 30, Gender: 'Male' }); - /// - /// - /// - /// - /// Adds the given entity to the context. - /// The entity to add - /// - /// - /// Persons.add(new $news.Types.Person({ Name: 'John', Email: 'john@example.com', Age: 30, Gender: 'Male' })); - /// - /// - /// - /// - /// var person = new $news.Types.Person({ Name: 'John', Email: 'john@example.com', Age: 30, Gender: 'Male' }); - /// Persons.add(person); - /// - /// - /// - - var data = entity; - if (entity instanceof $data.EntityWrapper) { - data = entity.getEntity(); - } else if (!(entity instanceof this.createNew)) { - data = new this.createNew(entity); - } - data.entityState = $data.EntityState.Added; - data.changedProperties = undefined; - data.context = this.entityContext; - this._trackEntity(data); - return data; - }, - - addMany: function(entities) { - var result = []; - var self = this; - entities.forEach(function (entity) { - result.push(self.add(entity)); - }); - return result; - }, - remove: function (entity) { - /// - /// Creates a typed entity and marks it as Deleted. - /// The init parameters whish is based on Entity - /// - /// Person will be marked as Deleted where an id is 5. Id is a key of entity. - /// Persons.remove({ Id: 5 }); - /// - /// - /// - /// - /// Marks the given entity as Deleted. - /// The entity to remove - /// - /// - /// Persons.remove(person); - /// - /// - /// - /// Person will be marked as Deleted where an Id is 5. Id is a key of entity. - /// Persons.add(new $news.Types.Person({ Id: 5 })); - /// - /// - /// - - var data = entity; - if (entity instanceof $data.EntityWrapper) { - data = entity.getEntity(); - } else if (!(entity instanceof this.createNew)) { - data = new this.createNew(entity); - } - data.entityState = $data.EntityState.Deleted; - data.changedProperties = undefined; - this._trackEntity(data); - }, - attach: function (entity, mode) { - /// - /// Creates a typed entity and adds to the Context with Unchanged state. - /// The init parameters whish is based on Entity - /// - /// - /// Persons.attach({ Id: 5, Email: 'newEmail@example.com' }); - /// - /// - /// - /// - /// Adds to the context and sets state Unchanged. - /// The entity to attach - /// - /// - /// Persons.attach(person); - /// - /// - /// - /// Set an entity's related entities without loading - /// - /// var categoryPromo = new $news.Types.Category({ Id: 5 }); - /// Category.attach(categoryPromo); - /// var article = new $news.Types.Article({ Title: 'New Article title', Body: 'Article body', Category: [ categoryPromo ] }); - /// Article.attach(article); - /// - /// - /// - - var data = entity; - if (entity instanceof $data.EntityWrapper) { - data = entity.getEntity(); - } else if (!(entity instanceof this.createNew)) { - data = new this.createNew(entity); - } - - for (var i = 0; i < this.entityContext.stateManager.trackedEntities.length; i++) { - var current = this.entityContext.stateManager.trackedEntities[i]; - if (current.data === data) - break; - if (current.data.equals(data)) { - Guard.raise(new Exception("Context already contains this entity!!!")); - } - } - - if (mode === true) { - if (data.changedProperties && data.changedProperties.length > 0) { - data.entityState = $data.EntityState.Modified; - } else { - data.entityState = $data.EntityState.Unchanged; - } - } else { - if (typeof mode === "string") mode = $data.EntityAttachMode[mode]; - var attachMode = mode || $data.EntityAttachMode[$data.EntityAttachMode.defaultMode]; - if (typeof attachMode === "function") { - attachMode.call($data.EntityAttachMode, data); - } else { - data.entityState = $data.EntityState.Unchanged; - data.changedProperties = undefined; - } - } - /*if (!keepChanges) { - data.entityState = $data.EntityState.Unchanged; - data.changedProperties = undefined; - }*/ - data.context = this.entityContext; - this._trackEntity(data); - }, - detach: function (entity) { - /// - /// Creates a typed entity and detach from the Context with Detached state. - /// The init parameters whish is based on Entity - /// - /// Person will be Detached where an id is 5. Id is a key of entity. - /// Persons.detach({ Id: 5 }); - /// - /// - /// - /// - /// Detach from the context and sets state Detached. - /// The entity to detach - /// - /// - /// Persons.detach(person); - /// - /// - /// - /// Person will be Detached where an Id is 5. Id is a key of entity. - /// Persons.add(new $news.Types.Person({ Id: 5 })); - /// - /// - /// - - var data = entity; - if (entity instanceof $data.EntityWrapper) { - data = entity.getEntity(); - } else if (!(entity instanceof this.createNew)) { - data = new this.createNew(entity); - } - - var existsItem; - var trackedEnt = this.entityContext.stateManager.trackedEntities; - for (var i = 0; i < trackedEnt.length; i++) { - if (trackedEnt[i].data.equals(data)) - existsItem = trackedEnt[i]; - } - - //var existsItem = this.entityContext.stateManager.trackedEntities.filter(function (i) { return i.data.equals(data); }).pop(); - if (existsItem) { - var idx = this.entityContext.stateManager.trackedEntities.indexOf(existsItem); - entity.entityState = $data.EntityState.Detached; - this.entityContext.stateManager.trackedEntities.splice(idx, 1); - return; - } - }, - attachOrGet: function (entity, mode) { - /// - /// Creates a typed entity and adds to the Context with Unchanged state. - /// The init parameters whish is based on Entity - /// - /// - /// Id is a key of entity. - /// var person = Persons.attachOrGet({ Id: 5 }); - /// - /// - /// - /// - /// If not in context then adds to it and sets state Unchanged. - /// The entity to detach - /// - /// - /// - /// var attachedPerson = Persons.attachOrGet(person); - /// - /// - /// - /// Id is a key of entity. - /// var p = new $news.Types.Person({ Id: 5 }); - /// var attachedPerson = Persons.attachOrGet(p); - /// - /// - /// - - var data = entity; - if (entity instanceof $data.EntityWrapper) { - data = entity.getEntity(); - } else if (!(entity instanceof this.createNew)) { - data = new this.createNew(entity); - } - - var existsItem; - var trackedEnt = this.entityContext.stateManager.trackedEntities; - for (var i = 0; i < trackedEnt.length; i++) { - if (trackedEnt[i].data.equals(data)) - existsItem = trackedEnt[i]; - } - //var existsItem = this.entityContext.stateManager.trackedEntities.filter(function (i) { return i.data.equals(data); }).pop(); - if (existsItem) { - return existsItem.data; - } - - if (typeof mode === "string") mode = $data.EntityAttachMode[mode]; - var attachMode = mode || $data.EntityAttachMode[$data.EntityAttachMode.defaultMode]; - if (typeof attachMode === "function") { - attachMode.call($data.EntityAttachMode, data); - } else { - data.entityState = $data.EntityState.Unchanged; - data.changedProperties = undefined; - } - //data.entityState = $data.EntityState.Unchanged; - //data.changedProperties = undefined; - data.context = this.entityContext; - this._trackEntity(data); - return data; - }, - //find: function (keys) { - // //todo global scope - // if (!this.entityKeys) { - // this.entityKeys = this.createNew.memberDefinition.filter(function (prop) { return prop.key; }, this); - // } - // this.entityContext.stateManager.trackedEntities.forEach(function (item) { - // if (item.entitySet == this) { - // var isOk = true; - // this.entityKeys.forEach(function (item, index) { isOK = isOk && (item.data[item.name] == keys[index]); }, this); - // if (isOk) { - // return item.data; - // } - // } - // }, this); - // //TODO: db call - // return null; - //}, - loadItemProperty: function (entity, memberDefinition, callback) { - /// - /// Loads a property of the entity through the storage provider. - /// Entity object - /// Property name - /// - /// Callback function - /// - /// - /// - /// - /// - /// Loads a property of the entity through the storage provider. - /// Entity object - /// Property name - /// - /// Success and error callbacks definition. - /// Example: [code]{ success: function(db) { .. }, error: function() { .. } }[/code] - /// - /// - /// - /// - /// Loads a property of the entity through the storage provider. - /// Entity object - /// Property definition - /// - /// Callback function - /// - /// - /// - /// - /// - /// Loads a property of the entity through the storage provider. - /// Entity object - /// Property definition - /// - /// Success and error callbacks definition. - /// Example: [code]{ success: function(db) { .. }, error: function() { .. } }[/code] - /// - /// - /// - - return this.entityContext.loadItemProperty(entity, memberDefinition, callback); - }, - saveChanges: function () { - return this.entityContext.saveChanges.apply(this.entityContext, arguments); - }, - addProperty: function (name, getter, setter) { - return this.elementType.addProperty.apply(this.elementType, arguments); - }, - expression: { - get: function () { - if (!this._expression) { - var ec = Container.createEntityContextExpression(this.entityContext); - //var name = entitySet.collectionName; - //var entitySet = this.entityContext[entitySetName]; - var memberdef = this.entityContext.getType().getMemberDefinition(this.collectionName); - var es = Container.createEntitySetExpression(ec, - Container.createMemberInfoExpression(memberdef), null, - this); - this._expression = es; - } - - return this._expression; - }, - set: function (value) { - this._expression = value; - } - }, - getFieldUrl: function (keys, field) { - return this.entityContext.getFieldUrl(keys, field, this); - }, - bulkInsert: function (fields, datas, callback) { - return this.entityContext.bulkInsert(this, fields, datas, callback); - } -}, null); -$data.EntityState = { - Detached:0, - Unchanged: 10, - Added: 20, - Modified: 30, - Deleted: 40 -};$data.Class.define("$data.EntityAttachMode", null, null, {}, { - defaultMode: 'Default', - AllChanged: function (data) { - var memDefs = data.getType().memberDefinitions.getPublicMappedProperties(); - for (var i = 0; i < memDefs.length; i++) { - data._setPropertyChanged(memDefs[i]); - } - data.entityState = $data.EntityState.Modified; - }, - KeepChanges: function (data) { - if (data.changedProperties && data.changedProperties.length > 0) { - data.entityState = $data.EntityState.Modified; - } else { - data.entityState = $data.EntityState.Unchanged; - } - }, - Default: function (data) { - data.entityState = $data.EntityState.Unchanged; - data.changedProperties = undefined; - } -});$data.Class.define('$data.EntityStateManager', null, null, -{ - constructor: function (entityContext) { - this.entityContext = null; - this.trackedEntities = []; - this.init(entityContext); - }, - init: function (entityContext) { - this.entityContext = entityContext; - }, - reset: function () { - this.trackedEntities = []; - } -}, null);$data.Class.define('$data.ItemStoreClass', null, null, { - constructor: function () { - var self = this; - self.itemStoreConfig = { - aliases: {}, - contextTypes: {} - } - - self.resetStoreToDefault('local', true); - $data.addStore = function () { - return self.addItemStoreAlias.apply(self, arguments); - }; - $data.implementation = self.implementation; - - $data.Entity.addMember('storeToken', { - get: function () { - if (this.storeConfigs && this.storeConfigs['default']) - return this.storeConfigs.stores[this.storeConfigs['default']]; - }, - set: function (value) { - self._setTypeStoreConfig(this, 'default', value); - } - }, true); - }, - itemStoreConfig: {}, - - addItemStoreAlias: function (name, contextFactoryOrToken, isDefault) { - var self = this; - var promise = new $data.PromiseHandler(); - var callback = promise.createCallback(); - - if ('string' === typeof name) { - //storeToken - if ('object' === typeof contextFactoryOrToken && 'factory' in contextFactoryOrToken) { - var type = Container.resolveType(contextFactoryOrToken.typeName); - - self.itemStoreConfig.aliases[name] = contextFactoryOrToken.factory; - self.itemStoreConfig.contextTypes[name] = type; - if (isDefault) { - self.itemStoreConfig['default'] = name; - } - - callback.success(); - return promise.getPromise(); - } - //contextFactory - else if ('function' === typeof contextFactoryOrToken) { - var preContext = contextFactoryOrToken(); - var contextPromise; - if (preContext && preContext instanceof $data.EntityContext) { - callback.success(preContext); - contextPromise = promise.getPromise(); - } else { - contextPromise = preContext; - } - - return contextPromise.then(function (ctx) { - if (typeof ctx === 'function') { - //factory resolve factory - return self.addItemStoreAlias(name, ctx, isDefault); - } - - if (ctx instanceof $data.EntityContext) { - return ctx.onReady() - .then(function (ctx) { - self.itemStoreConfig.aliases[name] = contextFactoryOrToken; - self.itemStoreConfig.contextTypes[name] = ctx.getType(); - if (isDefault) { - self.itemStoreConfig['default'] = name; - } - - return ctx; - }); - } else { - promise = new $data.PromiseHandler(); - callback = promise.createCallback(); - callback.error(new Exception('factory dont have context instance', 'Invalid arguments')); - return promise.getPromise(); - } - }); - } - } - - callback.error(new Exception('Name or factory missing', 'Invalid arguments')); - return promise.getPromise(); - }, - resetStoreToDefault: function (name, isDefault) { - this.itemStoreConfig.aliases[name] = this._getDefaultItemStoreFactory; - delete this.itemStoreConfig.contextTypes[name]; - if (isDefault) { - this.itemStoreConfig['default'] = name; - } - }, - _setStoreAlias: function (entity, storeToken) { - if ('object' === typeof storeToken && !entity.storeToken) - entity.storeToken = storeToken - return entity; - }, - _getStoreAlias: function (entity, storeAlias) { - var type; - if (entity instanceof $data.Entity) { - var alias = storeAlias || entity.storeToken; - if (alias) { - return alias; - } else { - type = entity.getType(); - } - } else { - type = entity; - } - - return storeAlias || (type.storeConfigs ? type.storeConfigs['default'] : undefined) || type.storeToken; - }, - _getStoreContext: function (aliasOrToken, type, nullIfInvalid) { - var contextPromise = this._getContextPromise(aliasOrToken, type); - - if (!contextPromise || contextPromise instanceof $data.EntityContext) { - var promise = new $data.PromiseHandler(); - var callback = promise.createCallback(); - callback.success(contextPromise); - contextPromise = promise.getPromise(); - } - - return contextPromise.then(function (context) { - if (context instanceof $data.EntityContext) { - return context.onReady(); - } else if (nullIfInvalid) { - return null; - } else { - var promise = new $data.PromiseHandler(); - var callback = promise.createCallback(); - callback.error(new Exception('factory return type error', 'Error')); - return promise.getPromise(); - } - }); - }, - _getContextPromise: function (aliasOrToken, type) { - /*Token*/ - if (aliasOrToken && 'object' === typeof aliasOrToken && 'function' === typeof aliasOrToken.factory) { - return aliasOrToken.factory(type); - } else if (aliasOrToken && 'object' === typeof aliasOrToken && 'object' === typeof aliasOrToken.args && 'string' === typeof aliasOrToken.typeName) { - var type = Container.resolveType(aliasOrToken.typeName); - return new type(JSON.parse(JSON.stringify(aliasOrToken.args))); - } - /*resolve alias from type (Token)*/ - else if (aliasOrToken && 'string' === typeof aliasOrToken && type.storeConfigs && type.storeConfigs.stores[aliasOrToken] && typeof type.storeConfigs.stores[aliasOrToken].factory === 'function') { - return type.storeConfigs.stores[aliasOrToken].factory(); - } - /*resolve alias from type (constructor options)*/ - else if (aliasOrToken && 'string' === typeof aliasOrToken && type.storeConfigs && type.storeConfigs.stores[aliasOrToken]) { - return this._getDefaultItemStoreFactory(type, type.storeConfigs.stores[aliasOrToken]); - } - /*resolve alias from ItemStore (factories)*/ - else if (aliasOrToken && 'string' === typeof aliasOrToken && this.itemStoreConfig.aliases[aliasOrToken]) { - return this.itemStoreConfig.aliases[aliasOrToken](type); - } - /*token is factory*/ - else if (aliasOrToken && 'function' === typeof aliasOrToken) { - return aliasOrToken(); - } - /*default no hint*/ - else { - return this.itemStoreConfig.aliases[this.itemStoreConfig['default']](type); - } - - }, - _getStoreEntitySet: function (storeAlias, instanceOrType) { - var aliasOrToken = this._getStoreAlias(instanceOrType, storeAlias); - var type = ("function" === typeof instanceOrType) ? instanceOrType : instanceOrType.getType();; - - return this._getStoreContext(aliasOrToken, type) - .then(function (ctx) { - var entitySet = ctx.getEntitySetFromElementType(type); - if (!entitySet) { - var d = new $data.PromiseHandler(); - var callback = d.createCallback(); - callback.error("EntitySet not exist for " + type.fullName); - return d.getPromise(); - } - return entitySet; - }); - }, - _getDefaultItemStoreFactory: function (instanceOrType, initStoreConfig) { - if (instanceOrType) { - var type = ("function" === typeof instanceOrType) ? instanceOrType : instanceOrType.getType(); - var typeName = $data.Container.resolveName(type) + "_items"; - var typeName = typeName.replace(/\./g, "_"); - - var storeConfig = $data.typeSystem.extend({ - collectionName: initStoreConfig && initStoreConfig.collectionName ? initStoreConfig.collectionName : 'Items', - tableName: typeName, - initParam: { provider: 'local', databaseName: typeName } - }, initStoreConfig); - - var contextDef = {}; - contextDef[storeConfig.collectionName] = { type: $data.EntitySet, elementType: type } - if (storeConfig.tableName) - contextDef[storeConfig.collectionName]['tableName'] = storeConfig.tableName; - - var inMemoryType = $data.EntityContext.extend(typeName, contextDef); - var ctx = new inMemoryType(storeConfig.initParam); - if (initStoreConfig && typeof initStoreConfig === 'object') - initStoreConfig.factory = ctx._storeToken.factory; - return ctx; - } - return undefined; - }, - implementation: function (name, contextOrAlias) { - var self = $data.ItemStore; - var result; - - if (typeof contextOrAlias === 'string') { - contextOrAlias = self.itemStoreConfig.contextTypes[contextOrAlias] - } else if (contextOrAlias instanceof $data.EntityContext) { - contextOrAlias = contextOrAlias.getType(); - } else if (!(typeof contextOrAlias === 'function' && contextOrAlias.isAssignableTo)) { - contextOrAlias = self.itemStoreConfig.contextTypes[self.itemStoreConfig['default']]; - } - - if (contextOrAlias) { - result = self._resolveFromContext(contextOrAlias, name); - } - - if (!result) { - result = Container.resolveType(name); - } - - return result; - }, - _resolveFromContext: function (contextType, name) { - var memDefs = contextType.memberDefinitions.getPublicMappedProperties(); - for (var i = 0; i < memDefs.length; i++) { - var memDef = memDefs[i]; - if (memDef.type) { - var memDefType = Container.resolveType(memDef.type); - if (memDefType.isAssignableTo && memDefType.isAssignableTo($data.EntitySet)) { - var elementType = Container.resolveType(memDef.elementType); - if (elementType.name === name) { - return elementType; - } - } - } - } - return null; - }, - - - //Entity Instance - EntityInstanceSave: function (storeAlias, hint) { - var self = $data.ItemStore; - var entity = this; - return self._getStoreEntitySet(storeAlias, entity) - .then(function (entitySet) { - return self._getSaveMode(entity, entitySet, hint, storeAlias) - .then(function (mode) { - mode = mode || 'add'; - switch (mode) { - case 'add': - entitySet.add(entity); - break; - case 'attach': - entitySet.attach(entity, true); - entity.entityState = $data.EntityState.Modified; - break; - default: - var d = new $data.PromiseHandler(); - var callback = d.createCallback(); - callback.error('save mode not supported: ' + mode); - return d.getPromise(); - } - - return entitySet.entityContext.saveChanges() - .then(function () { self._setStoreAlias(entity, entitySet.entityContext.storeToken); return entity; }); - }); - }); - }, - EntityInstanceRemove: function (storeAlias) { - var self = $data.ItemStore; - var entity = this; - return self._getStoreEntitySet(storeAlias, entity) - .then(function (entitySet) { - entitySet.remove(entity); - - return entitySet.entityContext.saveChanges() - .then(function () { return entity; }); - }); - }, - EntityInstanceRefresh: function (storeAlias, keepStore) { - var self = $data.ItemStore; - var entity = this; - var entityType = entity.getType(); - - var key = self._getKeyObjectFromEntity(entity, entityType); - - return entityType.read(key, storeAlias) - .then(function (loadedEntity) { - entityType.memberDefinitions.getPublicMappedProperties().forEach(function (memDef) { - entity[memDef.name] = loadedEntity[memDef.name]; - }); - entity.storeToken = (keepStore ? entity.storeToken : undefined) || loadedEntity.storeToken; - entity.changedProperties = undefined; - return entity; - }); - }, - - //Entity Type - EntityInheritedTypeProcessor: function (type) { - var self = $data.ItemStore; - type.readAll = self.EntityTypeReadAll(type); - type.read = self.EntityTypeRead(type); - type.removeAll = self.EntityTypeRemoveAll(type); - type.remove = self.EntityTypeRemove(type); - type.get = self.EntityTypeGet(type); //Not complete - type.save = self.EntityTypeSave(type); - type.addMany = self.EntityTypeAddMany(type); - type.itemCount = self.EntityTypeItemCount(type); - type.query = self.EntityTypeQuery(type); - type.takeFirst = self.EntityTypeTakeFirst(type); - - type.setStore = self.EntityTypeSetStore(type); - }, - EntityTypeReadAll: function (type) { - return function (storeAlias) { - var self = $data.ItemStore; - return self._getStoreEntitySet(storeAlias, type) - .then(function (entitySet) { - return entitySet.forEach(function (item) { self._setStoreAlias(item, entitySet.entityContext.storeToken); }); - }); - } - }, - EntityTypeRemoveAll: function (type) { - return function (storeAlias) { - var self = $data.ItemStore; - return self._getStoreEntitySet(storeAlias, type) - .then(function (entitySet) { - return entitySet.toArray().then(function (items) { - items.forEach(function (item) { - entitySet.remove(item); - }); - - return entitySet.entityContext.saveChanges() - .then(function () { return items; }); - }); - }); - } - }, - EntityTypeRead: function (type) { - return function (key, storeAlias) { - var self = $data.ItemStore; - return self._getStoreEntitySet(storeAlias, type) - .then(function (entitySet) { - try { - var singleParam = self._findByIdQueryable(entitySet, key); - return entitySet.single(singleParam.predicate, singleParam.thisArgs) - .then(function (item) { return self._setStoreAlias(item, entitySet.entityContext.storeToken); }); - } catch (e) { - var d = new $data.PromiseHandler(); - var callback = d.createCallback(); - callback.error(e); - return d.getPromise(); - } - }); - }; - }, - EntityTypeGet: function (type) { - return function (key, storeAlias) { - var self = $data.ItemStore; - var item = new type(self._getKeyObjectFromEntity(key)); - item.refresh(storeAlias); - return item; - }; - }, - EntityTypeSave: function (type) { - return function (initData, storeAlias, hint) { - - var self = $data.ItemStore; - var instance = new type(initData); - return instance.save(storeAlias, hint); - } - }, - EntityTypeAddMany: function (type) { - return function (initDatas, storeAlias) { - var self = $data.ItemStore; - return self._getStoreEntitySet(storeAlias, type) - .then(function (entitySet) { - var items = entitySet.addMany(initDatas); - return entitySet.entityContext.saveChanges() - .then(function () { - return items; - }); - }); - } - }, - EntityTypeRemove: function (type) { - return function (key, storeAlias) { - var self = $data.ItemStore; - var entityPk = type.memberDefinitions.getKeyProperties(); - var entity; - if (entityPk.length === 1) { - var obj = {}; - obj[entityPk[0].name] = key; - entity = new type(obj); - } else { - entity = new type(key); - } - return entity.remove(storeAlias); - } - }, - EntityTypeItemCount: function (type) { - return function (storeAlias) { - var self = $data.ItemStore; - return self._getStoreEntitySet(storeAlias, type) - .then(function (entitySet) { - return entitySet.length(); - }); - } - }, - EntityTypeQuery: function (type) { - return function (predicate, thisArg, storeAlias) { - var self = $data.ItemStore; - return self._getStoreEntitySet(storeAlias, type) - .then(function (entitySet) { - return entitySet.filter(predicate, thisArg).forEach(function (item) { self._setStoreAlias(item, entitySet.entityContext.storeToken); }); - }); - } - }, - EntityTypeTakeFirst: function (type) { - return function (predicate, thisArg, storeAlias) { - var self = $data.ItemStore; - return self._getStoreEntitySet(storeAlias, type) - .then(function (entitySet) { - return entitySet.first(predicate, thisArg) - .then(function (item) { return self._setStoreAlias(item, entitySet.entityContext.storeToken); }); - }); - } - }, - - EntityTypeSetStore: function (type) { - return function (name, config) { - if (typeof name === 'object' && typeof config === 'undefined') { - config = name; - name = 'default'; - } - - var self = $data.ItemStore; - - var defStoreConfig = {}; - if (config) { - if (config.tableName) { - defStoreConfig.tableName = config.tableName; - delete config.tableName; - } - - if (config.collectionName) { - defStoreConfig.collectionName = config.collectionName; - delete config.collectionName; - } - - if (typeof config.dataSource === 'string') { - var ds = config.dataSource; - if (ds.lastIndexOf('/') === ds.length - 1) { - ds = ds.substring(0, ds.lastIndexOf('/')); - } - var parsedApiUrl = ds.substring(0, ds.lastIndexOf('/')); - if (!defStoreConfig.tableName) - defStoreConfig.tableName = ds.substring(ds.lastIndexOf('/') + 1); - - var provider = config.provider || config.name; - switch (provider) { - case 'oData': - config.oDataServiceHost = config.oDataServiceHost || parsedApiUrl; - break; - case 'webApi': - config.apiUrl = config.apiUrl || parsedApiUrl; - break; - default: - break; - } - } - - - } else { - config = { name: 'local' }; - } - - defStoreConfig.initParam = config; - self._setTypeStoreConfig(type, name, defStoreConfig); - - return type; - } - }, - _setTypeStoreConfig: function(type, name, config){ - if (!type.storeConfigs) { - type.storeConfigs = { - stores: {} - }; - } - type.storeConfigs.stores[name] = config; - if (name === 'default') { - type.storeConfigs['default'] = name; - } - }, - - _findByIdQueryable: function (set, keys) { - var keysProps = set.defaultType.memberDefinitions.getKeyProperties(); - if (keysProps.length > 1 && keys && 'object' === typeof keys) { - var predicate = "", thisArgs = {}; - for (var i = 0; i < keysProps.length; i++) { - if (i > 0) predicate += " && "; - - var key = keysProps[i]; - predicate += "it." + key.name + " == this." + key.name; - thisArgs[key.name] = keys[key.name]; - } - - return { - predicate: predicate, - thisArgs: thisArgs - }; - } else if (keysProps.length === 1) { - return { - predicate: "it." + keysProps[0].name + " == this.value", - thisArgs: { value: keys } - }; - } else { - throw 'invalid keys'; - } - }, - _getKeyObjectFromEntity: function (obj, entityType) { - var key; - var keyDefs = entityType.memberDefinitions.getKeyProperties(); - if (keyDefs.length === 1) - key = obj && typeof obj === 'object' ? obj[keyDefs[0].name] : obj; - else { - key = {}; - - for (var i = 0; i < keyDefs.length; i++) { - key[keyDefs[0].name] = obj ? obj[keyDefs[0].name] : obj; - } - } - - return key; - }, - _getSaveMode: function (entity, entitySet, hint, storeAlias) { - var self = this; - var promise = new $data.PromiseHandler(); - var callback = promise.createCallback(); - var entityType = entity.getType(); - - switch (true) { - case hint === 'update': - callback.success('attach'); break; - case hint === 'new': - callback.success('add'); break; - case false === entityType.memberDefinitions.getKeyProperties().every(function (keyDef) { return entity[keyDef.name]; }): - callback.success('add'); break; - case !!entity.storeToken: - callback.success('attach'); break; - break; - default: - //use the current entity store informations - storeAlias = this._getStoreAlias(entity, storeAlias); - entityType.read(self._getKeyObjectFromEntity(entity, entityType), storeAlias) - .then(function () { callback.success('attach'); }) - .fail(function () { callback.success('add'); }); - break; - } - - return promise.getPromise(); - }, - - //EntityContext - ContextRegister: function (storageProviderCfg) { - //context instance - var self = this; - var args = JSON.parse(JSON.stringify(storageProviderCfg)); - this.storeToken = { - typeName: this.getType().fullName, - args: args, - factory: function () { - return new (self.getType())(args); - } - } - - //set elementType storetoken - var members = this.getType().memberDefinitions.getPublicMappedProperties(); - for (var i = 0; i < members.length; i++) { - var item = members[i]; - if (item.type) { - var itemResolvedDataType = Container.resolveType(item.type); - if (itemResolvedDataType && itemResolvedDataType.isAssignableTo && itemResolvedDataType.isAssignableTo($data.EntitySet)) { - var elementType = Container.resolveType(item.elementType); - if (!elementType.storeToken) { - elementType.storeToken = this.storeToken; - } - } - } - } - - }, - QueryResultModifier: function (query) { - var self = $data.ItemStore; - var context = query.context; - var type = query.modelBinderConfig.$type; - if ('string' === typeof type) { - type = Container.resolveType(type); - } - - if (type === $data.Array && query.modelBinderConfig.$item && query.modelBinderConfig.$item.$type) { - type = query.modelBinderConfig.$item.$type; - } - - //TODO: runs when model binding missed (inmemory) - if ((typeof type === 'undefined' && query.result && query.result[0] instanceof $data.Entity)) { - var navProps = !type ? [] : type.memberDefinitions.getPublicMappedProperties().filter(function (memDef) { - return !!memDef.inverseProperty; - }); - - for (var i = 0; i < query.result.length; i++) { - self._setStoreAlias(query.result[i], context.storeToken); - - for (var j = 0; j < navProps.length; j++) { - var navProp = navProps[j]; - if (query.result[i][navProp.name] instanceof $data.Entity) { - self._setStoreAlias(query.result[i][navProp.name], context.storeToken); - } else if (Array.isArray(query.result[i][navProp.name])) { - for (var k = 0; k < query.result[i][navProp.name].length; k++) { - if (query.result[i][navProp.name][k] instanceof $data.Entity) { - self._setStoreAlias(query.result[i][navProp.name][k], context.storeToken); - } - } - } - } - } - } - } -}); -$data.ItemStore = new $data.ItemStoreClass(); - -$data.Entity.addMember('field', function (propName) { - var def = this.memberDefinitions.getMember(propName); - if (def) { - if (def.definedBy === this) { - return new $data.MemberWrapper(def); - } else { - Guard.raise(new Exception("Member '" + propName + "' defined on '" + def.definedBy.fullName + "'!", 'Invalid Operation')); - } - } else { - Guard.raise(new Exception("Member '" + propName + "' not exists!", 'Invalid Operation')); - } - - return this; -}, true); - - -$data.Class.define('$data.MemberWrapper', null, null, { - constructor: function (memberDefinition) { - this.memberDefinition = memberDefinition; - }, - setKey: function (value) { - this.memberDefinition.key = value || value === undefined ? true : false; - return this; - }, - setComputed: function (value) { - this.memberDefinition.computed = value || value === undefined ? true : false; - return this; - }, - setRequired: function (value) { - this.memberDefinition.required = value || value === undefined ? true : false; - return this; - }, - setNullable: function (value) { - this.memberDefinition.nullable = value || value === undefined ? true : false; - return this; - }, - changeDefinition: function (attr, value) { - this.memberDefinition[attr] = value; - return this; - } -}); - -$data.Class.define('$data.StorageProviderLoaderBase', null, null, { - isSupported: function (providerName) { - $data.Trace.log('Detecting ' + providerName + ' provider support'); - var supported = true; - switch (providerName) { - case 'indexedDb': - supported = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || (window.msIndexedDB && !(/^file:/.test(window.location.href))); - break; - case 'storm': - supported = 'XMLHttpRequest' in window; - break; - case 'webSql': - case 'sqLite': - supported = 'openDatabase' in window; - break; - case 'LocalStore': - supported = 'localStorage' in window && window.localStorage ? true : false; - break; - case 'sqLite': - supported = 'openDatabase' in window; - break; - case 'mongoDB': - supported = $data.mongoDBDriver; - break; - default: - break; - } - $data.Trace.log(providerName + ' provider is ' + (supported ? '' : 'not') + ' supported'); - return supported; - }, - scriptLoadTimeout: { type: 'int', value: 1000 }, - scriptLoadInterval: { type: 'int', value: 50 }, - npmModules: { - value: { - 'indexedDb': 'jaydata-indexeddb', - 'InMemory': 'jaydata-inmemory', - 'LocalStore': 'jaydata-inmemory', - 'mongoDB': 'jaydata-mongodb', - 'oData': 'jaydata-odata', - 'webApi': 'jaydata-webapi', - 'sqLite': 'jaydata-sqlite', - 'webSql': 'jaydata-sqlite', - 'storm': 'jaydata-storm' - } - }, - ProviderNames: { - value: { - 'indexedDb': 'IndexedDb', - 'InMemory': 'InMemory', - 'LocalStore': 'InMemory', - 'oData': 'oData', - 'webApi': 'WebApi', - 'sqLite': 'SqLite', - 'webSql': 'SqLite', - 'storm': 'Storm' - } - }, - load: function (providerList, callback) { - $data.RegisteredStorageProviders = $data.RegisteredStorageProviders || {}; - - $data.Trace.log('Loading provider(s): ' + providerList); - callback = $data.typeSystem.createCallbackSetting(callback); - - var self = this; - var cacheKey = providerList.join(','); - self._fallbackCache = self._fallbackCache || {}; - - if (self._fallbackCache[cacheKey]) { - callback.success(self._fallbackCache[cacheKey]); - } else { - this.find(providerList, { - success: function (provider, selectedProvider) { - self._fallbackCache[cacheKey] = provider; - callback.success.call(this, provider); - }, - error: callback.error - }); - } - }, - find: function (providerList, callback) { - var currentProvider = providerList.shift(); - var currentProvider = this.getVirtual(currentProvider); - if(Array.isArray(currentProvider)){ - providerList = currentProvider; - currentProvider = providerList.shift(); - } - - while (currentProvider && !this.isSupported(currentProvider)) { - currentProvider = providerList.shift(); - } - - $data.Trace.log('First supported provider is ' + currentProvider); - - if (!currentProvider){ - $data.Trace.log('Provider fallback failed'); - callback.error(); - } - - if ($data.RegisteredStorageProviders) { - $data.Trace.log('Is the ' + currentProvider + ' provider already registered?'); - var provider = $data.RegisteredStorageProviders[currentProvider]; - if (provider) { - $data.Trace.log(currentProvider + ' provider registered'); - callback.success(provider) - return; - }else{ - $data.Trace.log(currentProvider + ' provider not registered'); - } - } - - if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { - // NodeJS - $data.Trace.log('node.js detected trying to load NPM module'); - this.loadNpmModule(currentProvider, providerList, callback); - } else { - $data.Trace.log('Browser detected trying to load provider'); - this.loadProvider(currentProvider, providerList, callback); - } - }, - loadProvider: function (currentProvider, providerList, callback) { - var self = this; - var mappedName = $data.StorageProviderLoader.ProviderNames[currentProvider] || currentProvider; - $data.Trace.log(currentProvider + ' provider is mapped to name ' + mappedName + 'Provider'); - if (mappedName) { - var url = this.getUrl(mappedName); - $data.Trace.log(currentProvider + ' provider from URL: ' + url); - - var loader = this.loadScript; - if (document && document.createElement) { - $data.Trace.log('document and document.createElement detected, using script element loader method'); - loader = this.loadScriptElement; - } - - loader.call(this, url, currentProvider, function (successful) { - var provider = $data.RegisteredStorageProviders[currentProvider]; - if (successful && provider) { - $data.Trace.log(currentProvider + ' provider successfully registered'); - callback.success(provider); - } else if (providerList.length > 0) { - $data.Trace.log(currentProvider + ' provider failed to load, trying to fallback to ' + providerList + ' provider(s)'); - self.find(providerList, callback); - } else { - $data.Trace.log(currentProvider + ' provider failed to load'); - callback.error(); - } - }); - } - }, - getUrl: function (providerName) { - var jaydataScriptMin = document.querySelector('script[src$="jaydata.min.js"]'); - var jaydataScript = document.querySelector('script[src$="jaydata.js"]'); - if (jaydataScriptMin) return jaydataScriptMin.src.substring(0, jaydataScriptMin.src.lastIndexOf('/') + 1) + 'jaydataproviders/' + providerName + 'Provider.min.js'; - else if (jaydataScript) return jaydataScript.src.substring(0, jaydataScript.src.lastIndexOf('/') + 1) + 'jaydataproviders/' + providerName + 'Provider.js'; - else return 'jaydataproviders/' + providerName + 'Provider.js'; - }, - loadScript: function (url, currentProvider, callback) { - if (!url){ - callback(false); - return; - } - - function getHttpRequest() { - if (window.XMLHttpRequest) - return new XMLHttpRequest(); - else if (window.ActiveXObject !== undefined) - return new ActiveXObject("MsXml2.XmlHttp"); - else{ - $data.Trace.log('XMLHttpRequest or MsXml2.XmlHttp ActiveXObject not found'); - callback(false); - return; - } - } - - var oXmlHttp = getHttpRequest(); - oXmlHttp.onreadystatechange = function () { - $data.Trace.log('HTTP request is in state: ' + oXmlHttp.readyState); - if (oXmlHttp.readyState == 4) { - if (oXmlHttp.status == 200 || oXmlHttp.status == 304) { - $data.Trace.log('HTTP request succeeded'); - $data.Trace.log('HTTP request response text: ' + oXmlHttp.responseText); - eval.call(window, oXmlHttp.responseText); - if (typeof callback === 'function') - callback(true); - else $data.Trace.log('Callback function is undefined'); - } else { - $data.Trace.log('HTTP request status: ', oXmlHttp.status); - if (typeof callback === 'function') - callback(false); - else $data.Trace.log('Callback function is undefined'); - } - } - }; - oXmlHttp.open('GET', url, true); - oXmlHttp.send(null); - }, - loadScriptElement: function (url, currentProvider, callback) { - var head = document.getElementsByTagName('head')[0] || document.documentElement; - - var script = document.createElement('script'); - script.type = 'text/javascript'; - script.src = url; - $data.Trace.log('Appending child ' + script + ' to ' + head); - head.appendChild(script); - - var loadInterval = this.scriptLoadInterval || 50; - var iteration = Math.ceil(this.scriptLoadTimeout / loadInterval); - $data.Trace.log('Script element watcher iterating ' + iteration + ' times'); - function watcher() { - $data.Trace.log('Script element watcher iteration ' + iteration); - var provider = $data.RegisteredStorageProviders[currentProvider]; - if (provider) { - $data.Trace.log(currentProvider + ' provider registered'); - callback(true); - } else { - iteration--; - if (iteration > 0) { - $data.Trace.log('Script element watcher next iteration'); - setTimeout(watcher, loadInterval); - } else { - $data.Trace.log('Script element loader failed'); - callback(false); - } - } - } - setTimeout(watcher, loadInterval); - }, - - loadNpmModule: function (currentProvider, providerList, callback) { - var provider = null; - try { - require(this.npmModules[currentProvider]); - provider = $data.RegisteredStorageProviders[currentProvider]; - $data.Trace.log('NPM module loader successfully registered ' + currentProvider + ' provider'); - } catch (e) { - $data.Trace.log('NPM module loader failed for ' + currentProvider + ' provider'); - } - - if (provider) { - callback.success(provider); - } else if (providerList.length > 0) { - this.find(providerList, callback); - } else { - callback.error(); - } - }, - - virtualProviders: { - type: $data.Array, - value: { - local: { - fallbacks: ['webSql', 'indexedDb', 'LocalStore'] - } - } - }, - getVirtual: function(name){ - if(this.virtualProviders[name]) - return [].concat(this.virtualProviders[name].fallbacks); - - return name; - } -}); - -$data.StorageProviderLoader = new $data.StorageProviderLoaderBase(); -$data.storageProviders = { - DbCreationType: { - Merge: 10, - DropTableIfChanged: 20, - DropTableIfChange: 20, - DropAllExistingTables: 30, - ErrorIfChange: 40, - DropDbIfChange: 50 - } -} - -$data.ConcurrencyMode = { Fixed: 'fixed', None: 'none' }; -$data.Class.define('$data.StorageProviderBase', null, null, -{ - constructor: function (schemaConfiguration, context) { - this.providerConfiguration = schemaConfiguration || {}; - - this.name = this.getType().name; - if ($data.RegisteredStorageProviders) { - var keys = Object.keys($data.RegisteredStorageProviders); - for (var i = 0; i < keys.length; i++) { - if (this instanceof $data.RegisteredStorageProviders[keys[i]]) { - this.name = keys[i]; - break; - } - } - } - }, - providers: {}, - supportedDataTypes: { value: [], writable: false }, - initializeStore: function (callBack) { - Guard.raise("Pure class"); - }, - - executeQuery: function (queryable, callBack) { - Guard.raise("Pure class"); - }, - loadRawData: function (tableName, callBack) { - callBack = $data.typeSystem.createCallbackSetting(callBack); - callBack.error(new Exception('loadRawData is not supported', 'Invalid Operation')); - }, - - buildIndependentBlocks: function (changedItems) { - /// - /// Build and processes a dependency graph from the changed items, - /// and generates blocks that can be inserted to the database sequentially. - /// - /// Array of changed items to build independent blocks from. - var edgesTo = []; - var edgesFrom = []; - - function hasOwnProperty(obj) { - /// - /// Returns true if object has own property (used for 'hashset'-like objects) - /// - /// Target object - /// True if the object has own property - for (var p in obj) { - if (obj.hasOwnProperty(p)) - return true; - } - return false; - } - - // Building edgesTo and edgesFrom arrays (containing only indeces of items in changedItems array. - for (var i = 0; i < changedItems.length; i++) { - var current = changedItems[i]; - if (!current.dependentOn || current.dependentOn.length == 0) { - // This item is independent - continue; - } - - var to = null; - // Iterating over items 'current' depends on - for (var j = 0; j < current.dependentOn.length; j++) { - var currentDependency = current.dependentOn[j]; - if (currentDependency.entityState == $data.EntityState.Unchanged) { - continue; - } - to = to || {}; - // Getting the index of current dependency - var ixDependendOn = -1; - for (var k = 0; k < changedItems.length; k++) { - if (changedItems[k].data == currentDependency) { - ixDependendOn = k; - break; - } - } - // Sanity check - if (ixDependendOn == -1) { - Guard.raise(new Exception('Dependent object not found', 'ObjectNotFound', current.dependentOn[j])); - } - // Setting edge in 'to' array - to[ixDependendOn] = true; - // Setting edge in 'from' array - from = edgesFrom[ixDependendOn] || {}; - from[i] = true; - edgesFrom[ixDependendOn] = from; - } - // Persisting found edges in edgesTo array - if (to !== null) - edgesTo[i] = to; - } - - // Array of sequentialyl independent blocks (containing objects, not just their id's) - var independentBlocks = []; - // Objects getting their dependency resolved in the current cycle. - var currentBlock = []; - // Filling currentBlock with initially independent objects. - for (var x = 0; x < changedItems.length; x++) { - if (!edgesTo.hasOwnProperty(x)) { - currentBlock.push(x); - } - } - while (currentBlock.length > 0) { - // Shifting currentBlock to cbix, - // and clearing currentBlock for next independent block - var cbix = [].concat(currentBlock); - currentBlock = []; - // Iterating over previous independent block, to generate the new one - for (var b = 0; b < cbix.length; b++) { - var dependentNodes = edgesFrom[cbix[b]]; - if (typeof dependentNodes !== 'undefined') { - for (var d in dependentNodes) { - // Removing edge from 'edgesTo' - delete edgesTo[d][cbix[b]]; - // Check if has any more dependency - if (!hasOwnProperty(edgesTo[d])) { - // It doesn't, so let's clean up a bit - delete edgesTo[d]; - // and push the item to 'currentBlock' - currentBlock.push(d); - } - } - } - // Clearing processed item from 'edgesFrom' - delete edgesFrom[cbix[b]]; - } - // Push cbix t to independentBlocks - var cb = []; - for (var c = 0; c < cbix.length; c++) { - var item = changedItems[cbix[c]]; - if (item.data.entityState != $data.EntityState.Unchanged) - cb.push(item); - } - if (cb.length > 0) - independentBlocks.push(cb); - } - return independentBlocks; - }, - getTraceString: function (queryable) { - Guard.raise("Pure class"); - }, - setContext: function (ctx) { - this.context = ctx; - }, - - _buildContinuationFunction: function (context, query) { - if (Array.isArray(query.result)) { - query.result.next = this._buildPagingMethod(context, query, 'next'); - query.result.prev = this._buildPagingMethod(context, query, 'prev'); - } - }, - _buildPagingMethod: function (context, query, mode) { - return function (onResult_items) { - var pHandler = new $data.PromiseHandler(); - var cbWrapper = pHandler.createCallback(onResult_items); - - var continuation = new $data.Expressions.ContinuationExpressionBuilder(mode); - var continuationResult = continuation.compile(query); - if (continuationResult.expression) { - var queryable = Container.createQueryable(context, continuationResult.expression); - queryable.defaultType = query.defaultType; - context.executeQuery(queryable, cbWrapper); - } else { - cbWrapper.error(new Exception(continuationResult.message, 'Invalid Operation', continuationResult)); - } - - return pHandler.getPromise(); - } - }, - - buildDbType_modifyInstanceDefinition: function (instanceDefinition, storageModel) { - var buildDbType_copyPropertyDefinition = function (propertyDefinition, refProp) { - var cPropertyDef; - if (refProp) { - cPropertyDef = JSON.parse(JSON.stringify(instanceDefinition[refProp])); - cPropertyDef.kind = propertyDefinition.kind; - cPropertyDef.name = propertyDefinition.name; - cPropertyDef.notMapped = false; - } else { - cPropertyDef = JSON.parse(JSON.stringify(propertyDefinition)); - } - - cPropertyDef.dataType = Container.resolveType(propertyDefinition.dataType); - cPropertyDef.type = cPropertyDef.dataType; - cPropertyDef.key = false; - cPropertyDef.computed = false; - return cPropertyDef; - }; - var buildDbType_createConstrain = function (foreignType, dataType, propertyName, prefix, keyPropertyName) { - var constrain = new Object(); - constrain[foreignType.name] = propertyName; - constrain[dataType.name] = keyPropertyName ? keyPropertyName : prefix + '__' + propertyName; - return constrain; - }; - - if (storageModel.Associations) { - storageModel.Associations.forEach(function (association) { - var addToEntityDef = false; - var foreignType = association.FromType; - var dataType = association.ToType; - var foreignPropName = association.ToPropertyName; - - var memDef = association.FromType.getMemberDefinition(association.FromPropertyName); - var keyProperties = []; - if (memDef && typeof memDef.keys === "string" && memDef.keys) { - keyProperties = [memDef.keys]; - } else if (memDef && Array.isArray(memDef.keys)) { - keyProperties = [].concat(memDef.keys); - } - - association.ReferentialConstraint = association.ReferentialConstraint || []; - - if ((association.FromMultiplicity == "*" && association.ToMultiplicity == "0..1") || (association.FromMultiplicity == "0..1" && association.ToMultiplicity == "1")) { - foreignType = association.ToType; - dataType = association.FromType; - foreignPropName = association.FromPropertyName; - addToEntityDef = true; - } - - foreignType.memberDefinitions.getPublicMappedProperties().filter(function (d) { return d.key }).forEach(function (d, i) { - var constraint = buildDbType_createConstrain(foreignType, dataType, d.name, foreignPropName, keyProperties[i]); - if (addToEntityDef) { - //instanceDefinition[foreignPropName + '__' + d.name] = buildDbType_copyPropertyDefinition(d, foreignPropName); - instanceDefinition[constraint[dataType.name]] = buildDbType_copyPropertyDefinition(d, foreignPropName); - - var dependentMemDef = dataType.getMemberDefinition(keyProperties[i]); - if (dependentMemDef) { - dependentMemDef.isDependentProperty = true; - dependentMemDef.navigationPropertyName = association.FromPropertyName; - } - } - association.ReferentialConstraint.push(constraint); - }, this); - }, this); - } - //Copy complex type properties - if (storageModel.ComplexTypes) { - storageModel.ComplexTypes.forEach(function (complexType) { - complexType.ReferentialConstraint = complexType.ReferentialConstraint || []; - - complexType.ToType.memberDefinitions.getPublicMappedProperties().forEach(function (d) { - instanceDefinition[complexType.FromPropertyName + '__' + d.name] = buildDbType_copyPropertyDefinition(d); - complexType.ReferentialConstraint.push(buildDbType_createConstrain(complexType.ToType, complexType.FromType, d.name, complexType.FromPropertyName)); - }, this); - }, this); - } - }, - buildDbType_generateConvertToFunction: function (storageModel) { - return function (logicalEntity) { - var dbInstance = new storageModel.PhysicalType(); - dbInstance.entityState = logicalEntity.entityState; - - //logicalEntity.changedProperties.forEach(function(memberDef){ - //}, this); - storageModel.PhysicalType.memberDefinitions.getPublicMappedProperties().forEach(function (property) { - if (logicalEntity[property.name] !== undefined) { - dbInstance[property.name] = logicalEntity[property.name]; - } - }, this); - - if (storageModel.Associations) { - storageModel.Associations.forEach(function (association) { - if ((association.FromMultiplicity == "*" && association.ToMultiplicity == "0..1") || (association.FromMultiplicity == "0..1" && association.ToMultiplicity == "1")) { - var complexInstance = logicalEntity[association.FromPropertyName]; - if (complexInstance !== undefined) { - association.ReferentialConstraint.forEach(function (constrain) { - if (complexInstance !== null) { - dbInstance[constrain[association.From]] = complexInstance[constrain[association.To]]; - } else { - dbInstance[constrain[association.From]] = null; - } - }, this); - } - } - }, this); - } - if (storageModel.ComplexTypes) { - storageModel.ComplexTypes.forEach(function (cmpType) { - var complexInstance = logicalEntity[cmpType.FromPropertyName]; - if (complexInstance !== undefined) { - cmpType.ReferentialConstraint.forEach(function (constrain) { - if (complexInstance !== null) { - dbInstance[constrain[cmpType.From]] = complexInstance[constrain[cmpType.To]]; - } else { - dbInstance[constrain[cmpType.From]] = null; - } - }, this); - } - }, this); - } - return dbInstance; - }; - }, - - bulkInsert: function (a, b, c, callback) { - callback.error(new Exception('Not Implemented')); - }, - - supportedFieldOperations: { - value: { - length: { dataType: "number", allowedIn: "filter, map" }, - substr: { dataType: "string", allowedIn: "filter", parameters: [{ name: "startFrom", dataType: "number" }, { name: "length", dataType: "number" }] }, - toLowerCase: { dataType: "string" } - }, - enumerable: true, - writable: true - }, - - resolveFieldOperation: function (operationName, expression, frameType) { - /// - var result = this.supportedFieldOperations[operationName]; - if (Array.isArray(result)) { - var i = 0; - for (; i < result.length; i++) { - if (result[i].allowedType === 'default' || Container.resolveType(result[i].allowedType) === Container.resolveType(expression.selector.memberDefinition.type) && - (frameType && result[i].allowedIn && - ( - (Array.isArray(result[i].allowedIn) && result[i].allowedIn.some(function(type){ return frameType === Container.resolveType(type); })) || - (!Array.isArray(result[i].allowedIn) && (frameType === Container.resolveType(result[i].allowedIn))) - ) - ) - ) { - result = result[i]; - break; - } - } - if (i === result.length) { - result = undefined; - } - } - - if (!result) { - Guard.raise(new Exception("Field operation '" + operationName + "' is not supported by the provider")); - }; - if (frameType && result.allowedIn) { - if ((result.allowedIn instanceof Array && !result.allowedIn.some(function (type) { return frameType === Container.resolveType(type); })) || - (!(result.allowedIn instanceof Array) && frameType !== Container.resolveType(result.allowedIn))) { - Guard.raise(new Exception(operationName + " not supported in: " + frameType.name)); - } - } - result.name = operationName; - return result; - }, - - supportedBinaryOperators: { - value: { - equal: { mapTo: 'eq', dataType: "boolean" } - }, - enumerable: true, - writable: true - }, - - resolveBinaryOperator: function (operator, expression, frameType) { - var result = this.supportedBinaryOperators[operator]; - if (!result) { - Guard.raise(new Exception("Binary operator '" + operator + "' is not supported by the provider")); - }; - if (frameType && result.allowedIn) { - if ((result.allowedIn instanceof Array && !result.allowedIn.some(function (type) { return frameType === Container.resolveType(type); })) || - (!(result.allowedIn instanceof Array) && frameType !== Container.resolveType(result.allowedIn))) { - Guard.raise(new Exception(operator + " not supported in: " + frameType.name)); - } - } - result.name = operator; - return result; - }, - - supportedUnaryOperators: { - value: { - not: { mapTo: 'not' } - }, - enumerable: true, - writable: true - }, - resolveUnaryOperator: function (operator, expression, frameType) { - var result = this.supportedUnaryOperators[operator]; - if (!result) { - Guard.raise(new Exception("Unary operator '" + operator + "' is not supported by the provider")); - }; - if (frameType && result.allowedIn) { - if ((result.allowedIn instanceof Array && !result.allowedIn.some(function (type) { return frameType === Container.resolveType(type); })) || - (!(result.allowedIn instanceof Array) && frameType !== Container.resolveType(result.allowedIn))) { - Guard.raise(new Exception(operator + " not supported in: " + frameType.name)); - } - } - result.name = operator; - return result; - }, - - supportedSetOperations: { - value: { - toArray: { invokable: true, allowedIn: [] } - }, - enumerable: true, - writable: true - }, - resolveSetOperations: function (operation, expression, frameType) { - var result = this.supportedSetOperations[operation]; - if (!result) { - Guard.raise(new Exception("Operation '" + operation + "' is not supported by the provider")); - }; - var allowedIn = result.allowedIn || []; - if (frameType && allowedIn) { - if ((allowedIn instanceof Array && !allowedIn.some(function (type) { return frameType === Container.resolveType(type); })) || - (!(allowedIn instanceof Array) && frameType !== Container.resolveType(allowedIn))) { - Guard.raise(new Exception(operation + " not supported in: " + frameType.name)); - } - } - return result; - }, - - resolveTypeOperations: function (operation, expression, frameType) { - Guard.raise(new Exception("Entity '" + expression.entityType.name + "' Operation '" + operation + "' is not supported by the provider")); - }, - - resolveContextOperations: function (operation, expression, frameType) { - Guard.raise(new Exception("Context '" + expression.instance.getType().name + "' Operation '" + operation + "' is not supported by the provider")); - }, - - makePhysicalTypeDefinition: function (entityDefinition, association) { - }, - - _beginTran: function (tables, isWrite, callBack) { - callBack.success(new $data.Transaction()); - }, - - getFieldUrl: function () { - return '#'; - }, - - supportedAutoincrementKeys: { - value: { } - } -}, -{ - onRegisterProvider: { value: new $data.Event() }, - registerProvider: function (name, provider) { - this.onRegisterProvider.fire({ name: name, provider: provider }, this); - $data.RegisteredStorageProviders = $data.RegisteredStorageProviders || []; - $data.RegisteredStorageProviders[name] = provider; - }, - getProvider: function (name) { - var provider = $data.RegisteredStorageProviders[name]; - if (!provider) - console.warn("Provider not found: '" + name + "'"); - return provider; - /*var provider = $data.RegisteredStorageProviders[name]; - if (!provider) - Guard.raise(new Exception("Provider not found: '" + name + "'", "Not Found")); - return provider;*/ - }, - isSupported: { - get: function () { return true; }, - set: function () { } - } -}); -$data.Class.define('$data.ServiceOperation', null, null, {}, { - translateDefinition: function (propertyDef, name, definedBy) { - propertyDef.serviceName = name; - var memDef = new $data.MemberDefinition(this.generateServiceOperation(propertyDef), this); - memDef.name = name; - return memDef; - }, - generateServiceOperation: function (cfg) { - - var fn; - if (cfg.serviceMethod) { - var returnType = cfg.returnType ? Container.resolveType(cfg.returnType) : {}; - if (returnType.isAssignableTo && returnType.isAssignableTo($data.Queryable)) { - fn = cfg.serviceMethod; - } else { - fn = function () { - var lastParam = arguments[arguments.length - 1]; - - var pHandler = new $data.PromiseHandler(); - var cbWrapper; - - var args = arguments; - if (typeof lastParam === 'function') { - cbWrapper = pHandler.createCallback(lastParam); - arguments[arguments.length - 1] = cbWrapper; - } else { - cbWrapper = pHandler.createCallback(); - arguments.push(cbWrapper); - } - - try { - var result = cfg.serviceMethod.apply(this, arguments); - if (result !== undefined) - cbWrapper.success(result); - } catch (e) { - cbWrapper.error(e); - } - - return pHandler.getPromise(); - } - } - - } else { - fn = function () { - var context = this; - var memberdef; - - var boundItem; - if (this instanceof $data.Entity || this instanceof $data.EntitySet) { - var entitySet; - if (this instanceof $data.Entity) { - if (this.context) { - context = this.context; - entitySet = context.getEntitySetFromElementType(this.getType()); - } else if (this.storeToken && typeof this.storeToken.factory === 'function') { - context = this.storeToken.factory(); - entitySet = context.getEntitySetFromElementType(this.getType()); - } else { - Guard.raise(new Exception("entity can't resolve context", 'Not Found!', this)); - return; - } - } else if (this instanceof $data.EntitySet) { - context = this.entityContext; - entitySet = this; - - var esDef = context.getType().getMemberDefinition(entitySet.name); - memberdef = $data.MemberDefinition.translateDefinition(esDef.actions[cfg.serviceName], cfg.serviceName, entitySet.getType()); - } - - - boundItem = { - data: this, - entitySet: entitySet - }; - } - - var virtualEntitySet = cfg.elementType ? context.getEntitySetFromElementType(Container.resolveType(cfg.elementType)) : null; - - var paramConstExpression = null; - if (cfg.params) { - paramConstExpression = []; - //object as parameter - if (arguments[0] && typeof arguments[0] === 'object' && arguments[0].constructor === $data.Object && cfg.params && cfg.params[0] && cfg.params[0].name in arguments[0]) { - var argObj = arguments[0]; - for (var i = 0; i < cfg.params.length; i++) { - var paramConfig = cfg.params[i]; - if (paramConfig.name && paramConfig.type && paramConfig.name in argObj) { - paramConstExpression.push(Container.createConstantExpression(argObj[paramConfig.name], Container.resolveType(paramConfig.type), paramConfig.name)); - } - } - } - //arg params - else { - for (var i = 0; i < cfg.params.length; i++) { - if (typeof arguments[i] == 'function') break; - - //TODO: check params type - var paramConfig = cfg.params[i]; - if (paramConfig.name && paramConfig.type && arguments[i] !== undefined) { - paramConstExpression.push(Container.createConstantExpression(arguments[i], Container.resolveType(paramConfig.type), paramConfig.name)); - } - } - } - } - - var ec = Container.createEntityContextExpression(context); - if (!memberdef) { - if (boundItem && boundItem.data) { - memberdef = boundItem.data.getType().getMemberDefinition(cfg.serviceName); - } else { - memberdef = context.getType().getMemberDefinition(cfg.serviceName); - } - } - var es = Container.createServiceOperationExpression(ec, - Container.createMemberInfoExpression(memberdef), - paramConstExpression, - cfg, - boundItem); - - //Get callback function - var clb = arguments[arguments.length - 1]; - if (!(typeof clb === 'function' || (typeof clb === 'object' /*&& clb.constructor === $data.Object*/ && (typeof clb.success === 'function' || typeof clb.error === 'function')))) { - clb = undefined; - } - - if (virtualEntitySet) { - var q = Container.createQueryable(virtualEntitySet, es); - if (clb) { - es.isTerminated = true; - return q._runQuery(clb); - } - return q; - } - else { - var returnType = cfg.returnType ? Container.resolveType(cfg.returnType) : null; - - var q = Container.createQueryable(context, es); - q.defaultType = returnType || $data.Object; - - if (returnType === $data.Queryable) { - q.defaultType = Container.resolveType(cfg.elementType); - if (clb) { - es.isTerminated = true; - return q._runQuery(clb); - } - return q; - } - es.isTerminated = true; - return q._runQuery(clb); - } - }; - }; - - var params = cfg.params || []; - $data.typeSystem.extend(fn, cfg, { params: params }); - - return fn; - } -}); - -$data.Class.define('$data.ServiceAction', $data.ServiceOperation, null, {}, { - generateServiceOperation: function (cfg) { - if (!cfg.method) { - cfg.method = 'POST'; //default Action method is POST - } - - return $data.ServiceOperation.generateServiceOperation.apply(this, arguments); - } -});$data.Base.extend('$data.EntityWrapper', { - getEntity: function () { - Guard.raise("pure object"); - } -}); -if (typeof jQuery !== 'undefined' && jQuery.ajax) { - $data.ajax = $data.ajax || jQuery.ajax; -} - -if (typeof WinJS !== 'undefined' && WinJS.xhr) { - $data.ajax = $data.ajax || function (options) { - $data.typeSystem.extend(options, { - dataType: 'json', - headers: {} - }); - var dataTypes = { - 'json': { - accept: 'application/json, text/javascript', - convert: JSON.parse - }, - 'text': { - accept: 'text/plain', - convert: function (e) { return e; } - }, - 'html': { - accept: 'text/html', - convert: function (e) { return e; } - }, - 'xml': { - accept: 'application/xml, text/xml', - convert: function (e) { - // TODO? - return e; - } - } - } - var dataTypeContext = dataTypes[options.dataType.toLowerCase()]; - - options.headers.Accept = dataTypeContext.accept; - - var successClb = options.success || $data.defaultSuccessCallback; - var errorClb = options.error || $data.defaultErrorCallback; - var progressClb = options.progress; - - var success = function (r) { - var result = dataTypeContext.convert(r.responseText); - successClb(result); - } - var error = function (r) { - var error = dataTypeContext.convert(r.responseText); - errorClb(error); - } - var progress = progressClb; - - WinJS.xhr(options) - .done(success, error, progress); - } -} - -if (typeof Ext !== 'undefined' && typeof Ext.Ajax) { - $data.ajax = $data.ajax || function (options) { - Ext.Ajax.request(options); - }; -} - -$data.ajax = $data.ajax || function () { - var cfg = arguments[arguments.length - 1]; - var clb = $data.typeSystem.createCallbackSetting(cfg); - clb.error("Not implemented"); -}; - - -$C('$data.modelBinder.FindProjectionVisitor', $data.Expressions.EntityExpressionVisitor, null, { - VisitProjectionExpression: function (expression) { - this.projectionExpression = expression; - } -}); - -$C('$data.modelBinder.ModelBinderConfigCompiler', $data.Expressions.EntityExpressionVisitor, null, { - constructor: function (query, includes, oDataProvider) { - this._query = query; - this._includes = includes; - this._isoDataProvider = oDataProvider || false; - }, - VisitSingleExpression: function (expression) { - this._defaultModelBinder(expression); - }, - VisitSomeExpression: function (expression) { - this._defaultModelBinder(expression); - }, - VisitFindExpression: function (expression) { - this._defaultModelBinder(expression); - }, - VisitEveryExpression: function (expression) { - this._defaultModelBinder(expression); - }, - VisitToArrayExpression: function (expression) { - this._defaultModelBinder(expression); - }, - VisitFirstExpression: function (expression) { - this._defaultModelBinder(expression); - }, - VisitForEachExpression: function (expression) { - this._defaultModelBinder(expression); - }, - VisitServiceOperationExpression: function (expression) { - if (expression.cfg.returnType) { - var returnType = Container.resolveType(expression.cfg.returnType); - if ((typeof returnType.isAssignableTo === 'function' && returnType.isAssignableTo($data.Queryable)) || returnType === $data.Array) { - this._defaultModelBinder(expression); - } else { - var builder = Container.createqueryBuilder(); - builder.modelBinderConfig['$type'] = returnType; - if (typeof returnType.isAssignableTo === 'function' && returnType.isAssignableTo($data.Entity)) { - builder.modelBinderConfig['$selector'] = ['json:' + expression.cfg.serviceName]; - } else { - builder.modelBinderConfig['$type'] = returnType; - builder.modelBinderConfig['$value'] = function (a, v) { - return (expression.cfg.serviceName in v) ? v[expression.cfg.serviceName] : v.value; - } - } - this.VisitExpression(expression, builder); - builder.resetModelBinderProperty(); - this._query.modelBinderConfig = builder.modelBinderConfig; - } - } - }, - VisitCountExpression: function (expression) { - var builder = Container.createqueryBuilder(); - - builder.modelBinderConfig['$type'] = $data.Array; - builder.selectModelBinderProperty('$item'); - builder.modelBinderConfig['$type'] = $data.Integer; - builder.modelBinderConfig['$source'] = 'cnt'; - builder.resetModelBinderProperty(); - this._query.modelBinderConfig = builder.modelBinderConfig; - }, - VisitBatchDeleteExpression: function (expression) { - var builder = Container.createqueryBuilder(); - - builder.modelBinderConfig['$type'] = $data.Array; - builder.selectModelBinderProperty('$item'); - builder.modelBinderConfig['$type'] = $data.Integer; - builder.modelBinderConfig['$source'] = 'cnt'; - builder.resetModelBinderProperty(); - this._query.modelBinderConfig = builder.modelBinderConfig; - }, - VisitConstantExpression: function (expression, builder) { - builder.modelBinderConfig['$type'] = expression.type; - builder.modelBinderConfig['$value'] = expression.value; - }, - - VisitExpression: function (expression, builder) { - var projVisitor = Container.createFindProjectionVisitor(); - projVisitor.Visit(expression); - - if (projVisitor.projectionExpression) { - this.Visit(projVisitor.projectionExpression, builder); - } else { - this.DefaultSelection(builder, this._query.defaultType, this._includes); - } - }, - _defaultModelBinder: function (expression) { - var builder = Container.createqueryBuilder(); - builder.modelBinderConfig['$type'] = $data.Array; - if (this._isoDataProvider) { - builder.modelBinderConfig['$selector'] = ['json:d.results', 'json:d', 'json:results']; - } - builder.modelBinderConfig['$item'] = {}; - builder.selectModelBinderProperty('$item'); - - this.VisitExpression(expression, builder); - - builder.resetModelBinderProperty(); - this._query.modelBinderConfig = builder.modelBinderConfig; - }, - _addPropertyToModelBinderConfig: function (elementType, builder) { - var storageModel = this._query.context._storageModel.getStorageModel(elementType); - if (elementType.memberDefinitions) { - elementType.memberDefinitions.getPublicMappedProperties().forEach(function (prop) { - if ((!storageModel) || (storageModel && !storageModel.Associations[prop.name] && !storageModel.ComplexTypes[prop.name])) { - - var type = Container.resolveType(prop.dataType); - if (!storageModel && this._query.context.storageProvider.supportedDataTypes.indexOf(type) < 0) { - //complex type - builder.selectModelBinderProperty(prop.name); - builder.modelBinderConfig['$type'] = type; - if (this._isoDataProvider) { - builder.modelBinderConfig['$selector'] = ['json:' + prop.name + '.results', 'json:' + prop.name]; - } else { - builder.modelBinderConfig['$selector'] = 'json:' + prop.name; - } - this._addPropertyToModelBinderConfig(type, builder); - builder.popModelBinderProperty(); - } else { - if (prop.key) { - builder.addKeyField(prop.name); - } - if (prop.concurrencyMode === $data.ConcurrencyMode.Fixed) { - builder.modelBinderConfig[prop.name] = { $selector: 'json:__metadata', $source: 'etag' } - } else if (type === $data.Array && prop.elementType) { - builder.selectModelBinderProperty(prop.name); - builder.modelBinderConfig['$type'] = type; - if (this._isoDataProvider) { - builder.modelBinderConfig['$selector'] = ['json:' + prop.name + '.results', 'json:' + prop.name]; - } else { - builder.modelBinderConfig['$selector'] = 'json:' + prop.name; - } - builder.selectModelBinderProperty('$item'); - var arrayElementType = Container.resolveType(prop.elementType); - builder.modelBinderConfig['$type'] = arrayElementType; - this._addPropertyToModelBinderConfig(arrayElementType, builder); - builder.popModelBinderProperty(); - builder.popModelBinderProperty(); - } else { - builder.modelBinderConfig[prop.name] = prop.name; - } - } - } - }, this); - } else { - /*builder._binderConfig = { - $selector: ['json:results'], - $type: $data.Array, - $item:{ - $type: elementType, - $value: function (meta, data) { return data; } - } - }*/ - builder._binderConfig.$item = builder._binderConfig.$item || {}; - builder.modelBinderConfig = builder._binderConfig.$item; - - - - } - if (storageModel) { - this._addComplexTypeProperties(storageModel.ComplexTypes, builder); - } - }, - _addComplexTypeProperties: function (complexTypes, builder) { - complexTypes.forEach(function (ct) { - if (ct.ToType !== $data.Array){ - builder.selectModelBinderProperty(ct.FromPropertyName); - builder.modelBinderConfig['$type'] = ct.ToType; - if (this._isoDataProvider) { - builder.modelBinderConfig['$selector'] = ['json:' + ct.FromPropertyName + '.results', 'json:' + ct.FromPropertyName]; - } else { - builder.modelBinderConfig['$selector'] = 'json:' + ct.FromPropertyName; - } - this._addPropertyToModelBinderConfig(ct.ToType, builder); - - builder.popModelBinderProperty(); - }else{ - var dt = ct.ToType; - var et = Container.resolveType(ct.FromType.memberDefinitions.getMember(ct.FromPropertyName).elementType); - if (dt === $data.Array && et && et.isAssignableTo && et.isAssignableTo($data.Entity)){ - config = { - $type: $data.Array, - $selector: 'json:' + ct.FromPropertyName, - $item: { - $type: et - } - }; - var md = et.memberDefinitions.getPublicMappedProperties(); - for (var i = 0; i < md.length; i++){ - config.$item[md[i].name] = { $type: md[i].type, $source: md[i].name }; - } - builder.modelBinderConfig[ct.FromPropertyName] = config; - }else{ - builder.modelBinderConfig[ct.FromPropertyName] = { - $type: ct.ToType, - $source: ct.FromPropertyName - }; - } - } - }, this); - }, - DefaultSelection: function (builder, type, allIncludes) { - //no projection, get all item from entitySet - builder.modelBinderConfig['$type'] = type; - - var storageModel = this._query.context._storageModel.getStorageModel(type); - this._addPropertyToModelBinderConfig(type, builder); - if (allIncludes) { - allIncludes.forEach(function (include) { - var includes = include.name.split('.'); - var association = null; - var tmpStorageModel = storageModel; - var itemCount = 0; - for (var i = 0; i < includes.length; i++) { - if (builder.modelBinderConfig.$item) { - builder.selectModelBinderProperty('$item'); - itemCount++; - } - builder.selectModelBinderProperty(includes[i]); - association = tmpStorageModel.Associations[includes[i]]; - tmpStorageModel = this._query.context._storageModel.getStorageModel(association.ToType); - } - if (this._isoDataProvider) { - builder.modelBinderConfig['$selector'] = ['json:' + includes[includes.length - 1] + '.results', 'json:' + includes[includes.length - 1]]; - } else { - builder.modelBinderConfig['$selector'] = 'json:' + includes[includes.length - 1]; - } - if (association.ToMultiplicity === '*') { - builder.modelBinderConfig['$type'] = $data.Array; - builder.selectModelBinderProperty('$item'); - builder.modelBinderConfig['$type'] = include.type; - this._addPropertyToModelBinderConfig(include.type, builder); - builder.popModelBinderProperty(); - } else { - builder.modelBinderConfig['$type'] = include.type; - this._addPropertyToModelBinderConfig(include.type, builder); - } - - for (var i = 0; i < includes.length + itemCount; i++) { - builder.popModelBinderProperty(); - } - }, this); - } - }, - VisitProjectionExpression: function (expression, builder) { - this.hasProjection = true; - this.Visit(expression.selector, builder); - - if (expression.selector && expression.selector.expression instanceof $data.Expressions.ObjectLiteralExpression) { - builder.modelBinderConfig['$type'] = expression.projectionAs || builder.modelBinderConfig['$type'] || $data.Object; - } - }, - VisitParametricQueryExpression: function (expression, builder) { - if (expression.expression instanceof $data.Expressions.EntityExpression || expression.expression instanceof $data.Expressions.EntitySetExpression) { - this.VisitEntityAsProjection(expression, builder); - } else { - this.Visit(expression.expression, builder); - } - - }, - VisitEntityAsProjection: function (expression, builder) { - this.mapping = ''; - this.Visit(expression.expression, builder); - var includes; - if (this.mapping && this._includes instanceof Array) { - includes = this._includes.filter(function (inc) { - return inc.name.indexOf(this.mapping + '.') === 0 - }, this); - includes = includes.map(function (inc) { - return { name: inc.name.replace(this.mapping + '.', ''), type: inc.type }; - }, this); - - if (includes.length > 0){ - this.DefaultSelection(builder, expression.expression.entityType, includes); - //console.warn('WARN: include for mapped properties is not supported!'); - } - } - - if (expression.expression instanceof $data.Expressions.EntityExpression) { - this.DefaultSelection(builder, expression.expression.entityType/*, includes*/) - } else if (expression.expression instanceof $data.Expressions.EntitySetExpression) { - builder.modelBinderConfig.$type = $data.Array; - builder.modelBinderConfig.$item = {}; - builder.selectModelBinderProperty('$item'); - this.DefaultSelection(builder, expression.expression.elementType /*, includes*/) - builder.popModelBinderProperty(); - } - - }, - - VisitEntityFieldExpression: function (expression, builder) { - this.Visit(expression.source, builder); - this.Visit(expression.selector, builder); - }, - VisitMemberInfoExpression: function (expression, builder) { - builder.modelBinderConfig['$type'] = expression.memberDefinition.type; - if (expression.memberDefinition.storageModel && expression.memberName in expression.memberDefinition.storageModel.ComplexTypes) { - this._addPropertyToModelBinderConfig(Container.resolveType(expression.memberDefinition.type), builder); - } else { - if (!(builder.modelBinderConfig.$type && Container.resolveType(builder.modelBinderConfig.$type).isAssignableTo && Container.resolveType(builder.modelBinderConfig.$type).isAssignableTo($data.Entity))) - builder.modelBinderConfig['$source'] = expression.memberName; - } - }, - VisitEntitySetExpression: function (expression, builder) { - if (expression.source instanceof $data.Expressions.EntityExpression) { - this.Visit(expression.source, builder); - this.Visit(expression.selector, builder); - } - - }, - VisitComplexTypeExpression: function (expression, builder) { - this.Visit(expression.source, builder); - this.Visit(expression.selector, builder); - - - if (('$selector' in builder.modelBinderConfig) && (builder.modelBinderConfig.$selector.length > 0)) { - if (builder.modelBinderConfig.$selector instanceof $data.Array) { - var temp = builder.modelBinderConfig.$selector[1]; - builder.modelBinderConfig.$selector[0] = temp + '.' + expression.selector.memberName + '.results'; - builder.modelBinderConfig.$selector[1] = temp + '.' + expression.selector.memberName; - } else { - builder.modelBinderConfig.$selector += '.' + expression.selector.memberName; - } - - } else { - if (this._isoDataProvider) { - builder.modelBinderConfig['$selector'] = ['json:' + expression.selector.memberName + '.results', 'json:' + expression.selector.memberName]; - } else { - builder.modelBinderConfig['$selector'] = 'json:' + expression.selector.memberName; - } - } - }, - VisitEntityExpression: function (expression, builder) { - this.Visit(expression.source, builder); - }, - VisitAssociationInfoExpression: function (expression, builder) { - if (('$selector' in builder.modelBinderConfig) && (builder.modelBinderConfig.$selector.length > 0)) { - if (builder.modelBinderConfig.$selector instanceof $data.Array) { - var temp = builder.modelBinderConfig.$selector[1]; - builder.modelBinderConfig.$selector[0] = temp + '.' + expression.associationInfo.FromPropertyName + '.results'; - builder.modelBinderConfig.$selector[1] = temp + '.' + expression.associationInfo.FromPropertyName; - } else { - builder.modelBinderConfig.$selector += '.' + expression.associationInfo.FromPropertyName; - } - - } else { - if (this._isoDataProvider) { - builder.modelBinderConfig['$selector'] = ['json:' + expression.associationInfo.FromPropertyName + '.results', 'json:' + expression.associationInfo.FromPropertyName]; - } else { - builder.modelBinderConfig['$selector'] = 'json:' + expression.associationInfo.FromPropertyName; - } - } - - if (this.mapping && this.mapping.length > 0) { this.mapping += '.'; } - this.mapping += expression.associationInfo.FromPropertyName; - }, - VisitObjectLiteralExpression: function (expression, builder) { - builder.modelBinderConfig['$type'] = $data.Object; - expression.members.forEach(function (of) { - this.Visit(of, builder); - }, this); - }, - VisitObjectFieldExpression: function (expression, builder) { - builder.selectModelBinderProperty(expression.fieldName); - if (expression.expression instanceof $data.Expressions.EntityExpression || expression.expression instanceof $data.Expressions.EntitySetExpression) { - this.VisitEntityAsProjection(expression, builder); - } else { - this.Visit(expression.expression, builder); - } - builder.popModelBinderProperty(); - } -}); -$data.Class.define("$data.Authentication.AuthenticationBase", null, null, { - constructor: function (cfg) { - this.configuration = cfg || {}; - this.Authenticated = false; - }, - /// { error:, abort:, pending:, success: } - Login: function (callbacks) { - Guard.raise("Pure class"); - }, - Logout: function () { - Guard.raise("Pure class"); - }, - CreateRequest: function (cfg) { - Guard.raise("Pure class"); - } - -}, null);$data.Class.define("$data.Authentication.Anonymous", $data.Authentication.AuthenticationBase, null, { - constructor: function (cfg) { - this.configuration = cfg || {}; - this.Authenticated = false; - }, - /// { error:, abort:, pending:, success: } - Login: function (callbacks) { - }, - Logout: function () { - }, - CreateRequest: function (cfg) { - $data.ajax(cfg); - } - -}, null);$data.Class.define("$data.Authentication.FacebookAuth", $data.Authentication.AuthenticationBase, null, { - constructor: function (cfg) { - this.configuration = $data.typeSystem.extend({ - Url_code: '', - type_code: '', - scope: '', - Url_token: '', - type_token: '', - access_token: '', - app_id: '' - }, cfg); - }, - Login: function (callbacks) { - if (this.Authenticated) { - return; - } - - var provider = this; - provider.configuration.stateCallbacks = callbacks || {}; - - $data.ajax({ - url: this.configuration.Url_code, - data: 'type=' + provider.configuration.type_code + '&client_id=' + provider.configuration.app_id + '&scope=' + provider.configuration.scope, - type: 'POST', - dataType: 'json', - success: function (data) { - if (typeof provider.configuration.stateCallbacks.pending == "function") - provider.configuration.stateCallbacks.pending(data); - provider._processRequestToken(data); - provider.Authenticated = true; - }, - error: function () { - if (typeof provider.configuration.stateCallbacks.error == "function") - provider.configuration.stateCallbacks.error(arguments); - } - }); - }, - Logout: function () { - this.Authenticated = false; - }, - CreateRequest: function (cfg) { - if (!cfg) - return; - var _this = this; - - if (cfg.url.indexOf('access_token=') === -1) { - if (cfg.url && this.Authenticated) { - var andChar = '?'; - if (cfg.url.indexOf(andChar) > 0) - andChar = '&'; - - if (this.configuration.access_token) - cfg.url = cfg.url + andChar + 'access_token=' + this.configuration.access_token; - } - } - - $data.ajax(cfg); - }, - _processRequestToken: function (verification_data) { - var provider = this; - - $data.ajax({ - url: provider.configuration.Url_token, - data: 'type=' + provider.configuration.type_token + '&client_id=' + provider.configuration.app_id + '&code=' + verification_data.code, - type: 'POST', - dataType: 'json', - success: function(result) { - provider.configuration.access_token = result.access_token; - if (typeof provider.configuration.stateCallbacks.success == "function") - provider.configuration.stateCallbacks.success(result); - }, - error: function(obj) { - var data = eval('(' + obj.responseText + ')'); - if (data.error) { - if (data.error.message == "authorization_pending") { - setTimeout(function() { - provider._processRequestToken(verification_data); - }, 2000); - } else if ("authorization_declined") { - if (typeof provider.configuration.stateCallbacks.abort == "function") - provider.configuration.stateCallbacks.abort(arguments); - } - } - } - }); - } -}, null);$data.Class.define("$data.Authentication.BasicAuth.BasicAuth", $data.Authentication.AuthenticationBase, null, { - constructor: function (cfg) { - this.configuration = $data.typeSystem.extend({ - Username: '', - Password: '' - }, cfg); - }, - Login: function (callbacks) { - if (callbacks && typeof callbacks.pending == "function") - callbacks.pending(); - }, - Logout: function () { - }, - CreateRequest: function (cfg) { - if (!cfg) - return; - var _this = this; - - var origBeforeSend = cfg.beforeSend; - cfg.beforeSend = function (xhr) { - xhr.setRequestHeader("Authorization", "Basic " + _this.__encodeBase64(_this.configuration.Username + ":" + _this.configuration.Password)); - - if(typeof origBeforeSend == "function") - origBeforeSend(xhr); - }; - - $data.ajax(cfg); - }, - __encodeBase64: function (val) { - var b64array = "ABCDEFGHIJKLMNOP" + - "QRSTUVWXYZabcdef" + - "ghijklmnopqrstuv" + - "wxyz0123456789+/" + - "="; - - input = val; - var base64 = ""; - var hex = ""; - var chr1, chr2, chr3 = ""; - var enc1, enc2, enc3, enc4 = ""; - var i = 0; - - do { - chr1 = input.charCodeAt(i++); - chr2 = input.charCodeAt(i++); - chr3 = input.charCodeAt(i++); - - enc1 = chr1 >> 2; - enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); - enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); - enc4 = chr3 & 63; - - if (isNaN(chr2)) { - enc3 = enc4 = 64; - } else if (isNaN(chr3)) { - enc4 = 64; - } - - base64 = base64 + - b64array.charAt(enc1) + - b64array.charAt(enc2) + - b64array.charAt(enc3) + - b64array.charAt(enc4); - chr1 = chr2 = chr3 = ""; - enc1 = enc2 = enc3 = enc4 = ""; - } while (i < input.length); - - return base64; - } -}, null); -$data.Class.define('$data.MetadataLoaderClass', null, null, { - load: function (metadataUri, callBack, config) { - - var cnf = { - EntityBaseClass: '$data.Entity', - ContextBaseClass: '$data.EntityContext', - AutoCreateContext: false, - DefaultNamespace: ('ns' + Math.random()).replace('.', '') + metadataUri.replace(/[^\w]/g, "_"), - ContextInstanceName: 'context', - EntitySetBaseClass: '$data.EntitySet', - CollectionBaseClass: 'Array', - url: metadataUri, - user: undefined, - password: undefined, - withCredentials: undefined, - httpHeaders: undefined, - - typeFilter: '', - navigation: true, - generateKeys: true, - dependentRelationsOnly: false - }; - - $data.typeSystem.extend( cnf, config || {}); - - if (cnf.DefaultNamespace && cnf.DefaultNamespace.lastIndexOf('.') !== (cnf.DefaultNamespace.length - 1)) - cnf.DefaultNamespace += '.'; - - this.factoryCache = this.factoryCache || {}; - callBack = $data.typeSystem.createCallbackSetting(callBack); - - if (metadataUri in this.factoryCache) { - - /*console.log("served from cache"); - console.dir(this.factoryCache[metadataUri]);*/ - callBack.success.apply({}, this.factoryCache[metadataUri]); - return; - } - - - - - var metadataUri; - if (cnf.url) { - cnf.SerivceUri = cnf.url.replace('/$metadata', ''); - if (cnf.url.indexOf('/$metadata') === -1) { - cnf.metadataUri = cnf.url.replace(/\/+$/, '') + '/$metadata'; - } else { - cnf.metadataUri = cnf.url; - } - } else { - callBack.error('metadata url is missing'); - } - - var self = this; - self._loadXMLDoc(cnf, function (xml, response) { - if (response.statusCode < 200 || response.statusCode > 299) { - callBack.error(response); - return; - } - - var versionInfo = self._findVersion(xml); - if (self.xsltRepoUrl) { - console.log('XSLT: ' + self.xsltRepoUrl + self._supportedODataVersionXSLT) - self._loadXMLDoc({ - metadataUri: self.xsltRepoUrl + self._supportedODataVersionXSLT, - user: cnf.user, - password: cnf.password, - httpHeaders: cnf.httpHeaders - }, function (xsl, response) { - if (response.statusCode < 200 || response.statusCode > 299) { - callBack.error(response); - return; - } - var text = response.responseText; - text = text.replace('xmlns:edm="@@VERSIONNS@@"', 'xmlns:edm="' + versionInfo.ns + '"'); - text = text.replace('@@VERSION@@', versionInfo.version); - - if (window.ActiveXObject === undefined) { - var parser = new DOMParser(); - xsl = parser.parseFromString(text, "text/xml"); - } else { - xsl = new ActiveXObject("Microsoft.XMLDOM"); - xsl.async = false; - xsl.loadXML(text); - } - - self._transform(callBack, versionInfo, xml, xsl, cnf); - }); - } else { - self._transform(callBack, versionInfo, xml, undefined, cnf); - } - - }); - }, - debugMode: { type: 'bool', value: false }, - xsltRepoUrl: { type: 'string', value: '' }, - - createFactoryFunc: function (ctxType, cnf, versionInfo) { - var self = this; - return function (config) { - if (ctxType) { - var cfg = $data.typeSystem.extend({ - name: 'oData', - oDataServiceHost: cnf.SerivceUri, - //maxDataServiceVersion: '', - user: cnf.user, - password: cnf.password, - withCredentials: cnf.withCredentials, - maxDataServiceVersion: versionInfo.maxVersion || '3.0' - }, config) - - - return new ctxType(cfg); - } else { - return null; - } - } - }, - - _transform: function (callBack, versionInfo, xml, xsl, cnf) { - var self = this; - var codeText = self._processResults(cnf.url, versionInfo, xml, xsl, cnf); - - try { - eval(codeText); - } catch (e) { - callBack.error(new Exception('SyntaxError', 'Unexpected model', [e, codeText])); - return; - } - - var ctxType; - if (!$data.generatedContexts || !(ctxType = $data.generatedContexts.pop())) { - callBack.error(new Exception('No context found in service', 'Not found', [cnf, codeText])); - return; - } - - var factoryFn = self.createFactoryFunc(ctxType, cnf, versionInfo); - this.factoryCache[cnf.url] = [factoryFn, ctxType]; - - factoryFn.type = ctxType; - - if (self.debugMode) { - factoryFn.codeText = codeText; - callBack.success(factoryFn, ctxType, codeText); - } - else { - callBack.success(factoryFn, ctxType); - } - }, - _loadXMLDoc: function (cnf, callback) { - var that = this; - if ($data.postMessageODataHandler) { - - if (cnf.user && cnf.password && (!cnf.httpHeaders || (cnf.httpHeaders && !cnf.httpHeaders['Authorization']))) { - httpHeader = httpHeader || {}; - httpHeader["Authorization"] = "Basic " + this.__encodeBase64(cnf.user + ":" + cnf.password); - } - - $data.postMessageODataHandler.requestProxy({ - url: cnf.metadataUri, - httpHeaders: cnf.httpHeaders, - success: function (response) { - var doc; - if (typeof module !== 'undefined' && typeof require !== 'undefined') { - doc = response.responseText; - } else if (window.ActiveXObject) { - doc = new ActiveXObject('Microsoft.XMLDOM'); - doc.async = 'false'; - doc.loadXML(response.responseText); - } else { - var parser = new DOMParser(); - doc = parser.parseFromString(response.responseText, 'text/xml'); - } - - callback(doc, response); - }, - error: function (e) { - that._loadXHTTP_XMLDoc(cnf, callback); - } - - }); - - } else { - this._loadXHTTP_XMLDoc(cnf, callback); - } - }, - _loadXHTTP_XMLDoc: function (cnf, callback) { - var xhttp = new XMLHttpRequest(); - xhttp.open("GET", cnf.metadataUri, true); - if (cnf.httpHeaders) { - Object.keys(cnf.httpHeaders).forEach(function (header) { - xhttp.setRequestHeader(header, cnf.httpHeaders[header]); - }); - } - xhttp.onreadystatechange = function () { - if (xhttp.readyState === 4) { - var response = { requestUri: cnf.metadataUri, statusCode: xhttp.status, statusText: xhttp.statusText, responseText: xhttp.responseText }; - callback(xhttp.responseXML || xhttp.responseText, response); - } - }; - - if (cnf.user && cnf.password && (!cnf.httpHeaders || (cnf.httpHeaders && !cnf.httpHeaders['Authorization']))) - xhttp.setRequestHeader("Authorization", "Basic " + this.__encodeBase64(cnf.user + ":" + cnf.password)); - - xhttp.send(""); - }, - _processResults: function (metadataUri, versionInfo, metadata, xsl, cnf) { - var transformXslt = this.getCurrentXSLTVersion(versionInfo, metadata); - cnf.typeFilter = this._prepareTypeFilter(metadata, versionInfo, cnf); - - if (window.ActiveXObject !== undefined) { - var xslt = new ActiveXObject("Msxml2.XSLTemplate.6.0"); - var xsldoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument.6.0"); - var xslproc; - xsldoc.async = false; - if (xsl) - xsldoc.load(xsl); - else - xsldoc.loadXML(transformXslt); - if (xsldoc.parseError.errorCode != 0) { - var myErr = xsldoc.parseError; - } else { - xslt.stylesheet = xsldoc; - var xmldoc = new ActiveXObject("Msxml2.DOMDocument.6.0"); - xmldoc.async = false; - xmldoc.load(metadata); - if (xmldoc.parseError.errorCode != 0) { - var myErr = xmldoc.parseError; - } else { - xslproc = xslt.createProcessor(); - xslproc.input = xmldoc; - - xslproc.addParameter('SerivceUri', cnf.SerivceUri); - xslproc.addParameter('EntityBaseClass', cnf.EntityBaseClass); - xslproc.addParameter('ContextBaseClass', cnf.ContextBaseClass); - xslproc.addParameter('AutoCreateContext', cnf.AutoCreateContext); - xslproc.addParameter('ContextInstanceName', cnf.ContextInstanceName); - xslproc.addParameter('EntitySetBaseClass', cnf.EntitySetBaseClass); - xslproc.addParameter('CollectionBaseClass', cnf.CollectionBaseClass); - xslproc.addParameter('DefaultNamespace', cnf.DefaultNamespace); - xslproc.addParameter('MaxDataserviceVersion', versionInfo.maxVersion || '3.0'); - xslproc.addParameter('AllowedTypesList', cnf.typeFilter); - xslproc.addParameter('GenerateNavigationProperties', cnf.navigation); - - xslproc.transform(); - return xslproc.output; - } - } - return ''; - } else if (typeof document !== 'undefined' && document.implementation && document.implementation.createDocument) { - var xsltStylesheet; - if (xsl) { - xsltStylesheet = xsl; - } else { - var parser = new DOMParser(); - xsltStylesheet = parser.parseFromString(transformXslt, "text/xml"); - } - - var xsltProcessor = new XSLTProcessor(); - xsltProcessor.importStylesheet(xsltStylesheet); - xsltProcessor.setParameter(null, 'SerivceUri', cnf.SerivceUri); - xsltProcessor.setParameter(null, 'EntityBaseClass', cnf.EntityBaseClass); - xsltProcessor.setParameter(null, 'ContextBaseClass', cnf.ContextBaseClass); - xsltProcessor.setParameter(null, 'AutoCreateContext', cnf.AutoCreateContext); - xsltProcessor.setParameter(null, 'ContextInstanceName', cnf.ContextInstanceName); - xsltProcessor.setParameter(null, 'EntitySetBaseClass', cnf.EntitySetBaseClass); - xsltProcessor.setParameter(null, 'CollectionBaseClass', cnf.CollectionBaseClass); - xsltProcessor.setParameter(null, 'DefaultNamespace', cnf.DefaultNamespace); - xsltProcessor.setParameter(null, 'MaxDataserviceVersion', versionInfo.maxVersion || '3.0'); - xsltProcessor.setParameter(null, 'AllowedTypesList', cnf.typeFilter); - xsltProcessor.setParameter(null, 'GenerateNavigationProperties', cnf.navigation); - resultDocument = xsltProcessor.transformToFragment(metadata, document); - - return resultDocument.textContent; - } else if (typeof module !== 'undefined' && typeof require !== 'undefined') { - var xslt = require('node_xslt'); - - return xslt.transform(xslt.readXsltString(transformXslt), xslt.readXmlString(metadata), [ - 'SerivceUri', "'" + cnf.SerivceUri + "'", - 'EntityBaseClass', "'" + cnf.EntityBaseClass + "'", - 'ContextBaseClass', "'" + cnf.ContextBaseClass + "'", - 'AutoCreateContext', "'" + cnf.AutoCreateContext + "'", - 'ContextInstanceName', "'" + cnf.ContextInstanceName + "'", - 'EntitySetBaseClass', "'" + cnf.EntitySetBaseClass + "'", - 'CollectionBaseClass', "'" + cnf.CollectionBaseClass + "'", - 'DefaultNamespace', "'" + cnf.DefaultNamespace + "'", - 'MaxDataserviceVersion', "'" + (versionInfo.maxVersion || '3.0') + "'", - 'AllowedTypesList', "'" + cnf.typeFilter + "'", - 'GenerateNavigationProperties', "'" + cnf.navigation + "'" - ]); - } - }, - _prepareTypeFilter: function (doc, versionInfo, cnf) { - var result = ''; - if (!(typeof doc === 'object' && "querySelector" in doc && "querySelectorAll" in doc)) - return result; - - var config = []; - if (typeof cnf.typeFilter === 'object' && cnf.typeFilter) { - var types = Object.keys(cnf.typeFilter); - for (var i = 0; i < types.length; i++) { - var cfg = cnf.typeFilter[types[i]]; - var typeData = {}; - if (typeof cfg === 'object' && cfg) { - if (Array.isArray(cfg)) { - typeData.Name = types[i]; - typeData.Fields = cfg; - } else { - typeData.Name = cfg.name || types[i]; - typeData.Fields = cfg.members || []; - } - } else if (cfg) { - typeData.Name = types[i]; - typeData.Fields = []; - } else { - continue; - } - - var typeShortName = typeData.Name; - var containerName = ""; - if (typeData.Name.lastIndexOf('.') > 0) - { - containerName = typeData.Name.substring(0, typeData.Name.lastIndexOf('.')); - typeShortName = typeData.Name.substring(typeData.Name.lastIndexOf('.') + 1); - } - - var conainers = doc.querySelectorAll("EntityContainer[Name = '" + containerName + "']"); - for (var j = 0; j < conainers.length; j++) { - var entitySetDef = conainers[j].querySelector("EntitySet[Name = '" + typeShortName + "']"); - if (entitySetDef != null) - { - typeData.Name = entitySetDef.attributes["EntityType"].value; - break; - } - - } - - config.push(typeData); - } - - var discoveredData; - if (cnf.dependentRelationsOnly) { - discoveredData = this._discoverProperyDependencies(config, doc, cnf.navigation, cnf.generateKeys); - } else { - discoveredData = this._discoverTypeDependencies(config, doc, cnf.navigation, cnf.generateKeys); - } - - var complex = doc.querySelectorAll("ComplexType"); - for (var i = 0; i < complex.length; i++) - { - var cns = complex[i].parentNode.attributes["Namespace"].value; - var data = !cns ? complex[i].attributes["Name"].value : (cns + "." + complex[i].attributes["Name"].value); - discoveredData.push({ Name: data, Fields: [] }); - } - - for (var i = 0; i < discoveredData.length; i++) - { - var row = discoveredData[i]; - if (row.Fields.length > 0) { - result += row.Name + ":" + row.Fields.join(",") + ";"; - } - else { - result += row.Name + ";"; - } - } - - } - - return result; - }, - _discoverTypeDependencies: function (types, doc, withNavPropertis, withKeys) { - var allowedTypes = []; - var allowedTypeNames = []; - var collect = []; - - for (var i = 0; i < types.length; i++) - { - var idx = collect.indexOf(types[i].Name); - if(idx >= 0){ - collect.splice(idx, 1); - } - this._discoverType(types[i], doc, allowedTypes, allowedTypeNames, withNavPropertis, withKeys, true, collect); - } - - for (var i = 0; i < collect.length; i++) - { - this._discoverType({ Name: collect[i], Fields: [] }, doc, allowedTypes, allowedTypeNames, withNavPropertis, withKeys, false, []); - } - - return allowedTypes; - }, - _discoverType: function(typeData, doc, allowedTypes, allowedTypeNames, withNavPropertis, withKeys, collectTypes, collectedTypes) { - var typeName = typeData.Name; - - if (allowedTypeNames.indexOf(typeName) >= 0) - { - return; - } - console.log("Discover: " + typeName); - - var typeShortName = typeName; - var typeNamespace = ''; - if (typeName.lastIndexOf('.') > 0) - { - typeNamespace = typeName.substring(0, typeName.lastIndexOf('.')); - typeShortName = typeName.substring(typeName.lastIndexOf('.') + 1); - } - - var schemaNode = doc.querySelector("Schema[Namespace = '" + typeNamespace + "']"); - if (schemaNode != null) - { - var typeNode = schemaNode.querySelector("EntityType[Name = '" + typeShortName + "'], ComplexType[Name = '" + typeShortName + "']"); - if (typeNode != null) - { - allowedTypes.push(typeData); - allowedTypeNames.push(typeName); - - if (withKeys && typeData.Fields.length > 0) { - var keys = typeNode.querySelectorAll("Key PropertyRef"); - if (keys != null) - { - for (var j = 0; j < keys.length; j++) - { - var keyField = keys[j].attributes["Name"].value; - if (typeData.Fields.indexOf(keyField) < 0) - typeData.Fields.splice(j, 0, keyField); - } - } - } - - if (withNavPropertis) - { - var navPropNodes = typeNode.querySelectorAll("NavigationProperty"); - for (var j = 0; j < navPropNodes.length; j++) - { - var navProp = navPropNodes[j]; - if (typeData.Fields.length == 0 || typeData.Fields.indexOf(navProp.attributes["Name"].value) >=0) - { - - var FromRole = navProp.attributes["FromRole"].value; - var ToRole = navProp.attributes["ToRole"].value; - - var association = schemaNode.querySelector("Association End[Role = '" + FromRole + "']:not([Type = '" + typeName + "'])"); - if (association == null) - { - association = schemaNode.querySelector("Association End[Role = '" + ToRole + "']:not([Type = '" + typeName + "'])"); - } - - if (association != null) - { - var nav_type = association.attributes["Type"].value; - - if (collectTypes) - { - if (collectedTypes.indexOf(nav_type) < 0 && allowedTypeNames.indexOf(nav_type) < 0) - collectedTypes.push(nav_type); - } - else - { - this._discoverType({ Name: nav_type, Fields: [] }, doc, allowedTypes, allowedTypeNames, withNavPropertis, withKeys, false, collectedTypes); - } - } - } - } - } - } - } - }, - - _discoverProperyDependencies: function (types, doc, withNavPropertis, withKeys) { - var allowedTypes = []; - var allowedTypeNames = types.map(function(t) { return t.Name; }); - - for (var i = 0; i < types.length; i++) - { - this._discoverProperties(types[i], doc, allowedTypes, allowedTypeNames, withNavPropertis, withKeys); - } - - return allowedTypes; - }, - _discoverProperties: function(typeData, doc, allowedTypes, allowedTypeNames, withNavPropertis, withKeys) { - var typeName = typeData.Name; - console.log("Discover: " + typeName); - - var hasProperty = typeData.Fields.length != 0; - var typeShortName = typeName; - var typeNamespace = ''; - if (typeName.lastIndexOf('.') > 0) - { - typeNamespace = typeName.substring(0, typeName.lastIndexOf('.')); - typeShortName = typeName.substring(typeName.lastIndexOf('.') + 1); - } - - var schemaNode = doc.querySelector("Schema[Namespace = '" + typeNamespace + "']"); - if (schemaNode != null) - { - var typeNode = schemaNode.querySelector("EntityType[Name = '" + typeShortName + "'], ComplexType[Name = '" + typeShortName + "']"); - if (typeNode != null) - { - allowedTypes.push(typeData); - - if (!hasProperty) - { - var properties = typeNode.querySelectorAll("Property"); - if (properties != null) - { - for (var j = 0; j < properties.length; j++) - { - var field = properties[j].attributes["Name"].value; - typeData.Fields.push(field); - } - } - - if (withNavPropertis) - { - var navPropNodes = typeNode.querySelectorAll("NavigationProperty"); - for (var j = 0; j < navPropNodes.length; j++) - { - var navProp = navPropNodes[j]; - var nav_name = navProp.attributes["Name"].value; - var types = [ navProp.attributes["FromRole"].value, navProp.attributes["ToRole"].value ]; - - var nav_type = ''; - for (var t = 0; t < types.length; t++) - { - var association = schemaNode.querySelector("Association End[Role = '" + types[t] + "']"); - if (association != null) - { - nav_type = association.attributes["Type"].value; - if (nav_type != typeName || t == 1) - break; - } - } - - if (allowedTypeNames.indexOf(nav_type) >= 0) - { - typeData.Fields.push(nav_name); - } - } - } - } - else if (withKeys) - { - var keys = typeNode.querySelectorAll("Key PropertyRef"); - if (keys != null) - { - for (var j = 0; j < keys.length; j++) - { - var keyField = keys[j].attributes["Name"].value; - if (typeData.Fields.indexOf(keyField) < 0) - typeData.Fields.splice(j, 0, keyField); - } - } - } - } - } - }, - - _findVersion: function (metadata) { - var maxDSVersion = ''; - - if (typeof metadata === 'object' && "getElementsByTagName" in metadata){ - var version = 'http://schemas.microsoft.com/ado/2008/09/edm'; - var item = metadata.getElementsByTagName('Schema'); - if (item) - item = item[0]; - if (item) - item = item.attributes; - if (item) - item = item.getNamedItem('xmlns'); - if (item) - version = item.value; - - var maxDSVersion = metadata.getElementsByTagName('edmx:DataServices')[0] || metadata.getElementsByTagName('DataServices')[0]; - if (maxDSVersion) - maxDSVersion = maxDSVersion.attributes.getNamedItem('m:MaxDataServiceVersion'); - if (maxDSVersion && version) - maxDSVersion = maxDSVersion.value; - - - var versionNum = this._supportedODataVersions[version]; - return { - ns: version, - version: versionNum || 'unknown', - maxVersion: maxDSVersion || this._maxDataServiceVersions[version || 'unknown'] - }; - }else if (typeof module !== 'undefined' && typeof require !== 'undefined'){ - var schemaXml = metadata; - - var schemaNamespace = 'http://schemas.microsoft.com/ado/2008/09/edm'; - var version = 'nodejs'; - for (var i in this._supportedODataVersions){ - if (schemaXml.search(new RegExp('= 0){ - schemaNamespace = i; - version = this._supportedODataVersions[i]; - break; - } - } - - return { - ns: schemaNamespace, - version: version, - maxVersion: this._maxDataServiceVersions[version || 'unknown'] - } - } - }, - _supportedODataVersions: { - value: { - "http://schemas.microsoft.com/ado/2006/04/edm": "V1", - "http://schemas.microsoft.com/ado/2008/09/edm": "V2", - "http://schemas.microsoft.com/ado/2009/11/edm": "V3", - "http://schemas.microsoft.com/ado/2007/05/edm": "V11", - "http://schemas.microsoft.com/ado/2009/08/edm": "V22" - } - }, - _maxDataServiceVersions: { - value: { - "http://schemas.microsoft.com/ado/2006/04/edm": "2.0", - "http://schemas.microsoft.com/ado/2008/09/edm": "2.0", - "http://schemas.microsoft.com/ado/2009/11/edm": "3.0", - "http://schemas.microsoft.com/ado/2007/05/edm": "2.0", - "http://schemas.microsoft.com/ado/2009/08/edm": "2.0" - } - }, - _supportedODataVersionXSLT: { - value: "JayDataContextGenerator.xslt" - }, - getCurrentXSLTVersion: function (versionInfo, metadata) { - return this._metadataConverterXSLT.replace('@@VERSIONNS@@', versionInfo.ns).replace('@@VERSION@@', versionInfo.version); - }, - __encodeBase64: function (val) { - var b64array = "ABCDEFGHIJKLMNOP" + - "QRSTUVWXYZabcdef" + - "ghijklmnopqrstuv" + - "wxyz0123456789+/" + - "="; - - var input = val; - var base64 = ""; - var hex = ""; - var chr1, chr2, chr3 = ""; - var enc1, enc2, enc3, enc4 = ""; - var i = 0; - - do { - chr1 = input.charCodeAt(i++); - chr2 = input.charCodeAt(i++); - chr3 = input.charCodeAt(i++); - - enc1 = chr1 >> 2; - enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); - enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); - enc4 = chr3 & 63; - - if (isNaN(chr2)) { - enc3 = enc4 = 64; - } else if (isNaN(chr3)) { - enc4 = 64; - } - - base64 = base64 + - b64array.charAt(enc1) + - b64array.charAt(enc2) + - b64array.charAt(enc3) + - b64array.charAt(enc4); - chr1 = chr2 = chr3 = ""; - enc1 = enc2 = enc3 = enc4 = ""; - } while (i < input.length); - - return base64; - }, - _metadataConverterXSLT: { - type: 'string', - value: - "\r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " Microsoft.Crm.Sdk.Data.Services.Product;Microsoft.Crm.Sdk.Data.Services.LeadAddress:Telephone1,City,UTCOffset;\r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " 0\">\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " 0\">\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " 0\">\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " 0\">\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " 0)\"/>\r\n" + - " 0)\"/>\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - "/*//////////////////////////////////////////////////////////////////////////////////////\r\n" + - "////// Autogenerated by JaySvcUtil.exe http://JayData.org for more info /////////\r\n" + - "////// oData @@VERSION@@ /////////\r\n" + - "//////////////////////////////////////////////////////////////////////////////////////*/\r\n" + - "(function(global, $data, undefined) {\r\n" + - "\r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " 0)\"/>\r\n" + - " \r\n" + - " \r\n" + - " 0)\"/>\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " 0)\"/>\r\n" + - " \r\n" + - " \r\n" + - " 0)\"/>\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " Info: generating type \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " 0)\"/>\r\n" + - " \r\n" + - " \r\n" + - " 0)\"/>\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " .extend('.', {\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " , \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " , \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " ,\r\n" + - " \r\n" + - " ,\r\n" + - " \r\n" + - " \r\n" + - " });\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - " .extend('', {\r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " ,\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " ,\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " });\r\n" + - "\r\n" + - " $data.generatedContexts = $data.generatedContexts || [];\r\n" + - " $data.generatedContexts.push();\r\n" + - " \r\n" + - " /*Context Instance*/\r\n" + - " = new ({ name:'oData', oDataServiceHost: '', maxDataServiceVersion: '' });\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - " \r\n" + - "})(window, $data);\r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " '\r\n" + - " \r\n" + - " ': { type: \r\n" + - " \r\n" + - " \r\n" + - " $data.ServiceAction\r\n" + - " \r\n" + - " \r\n" + - " $data.ServiceOperation\r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " , params: [\r\n" + - " 1) or (($IsBindable = 'false' or $IsBindable = '') and position() > 0)]\">\r\n" + - " { name: '\r\n" + - " \r\n" + - " ', type: '\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " ' }\r\n" + - " , \r\n" + - " \r\n" + - " ]\r\n" + - "\r\n" + - " }\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " , returnType: \r\n" + - " \r\n" + - " null\r\n" + - " $data.Queryable\r\n" + - " \r\n" + - " '\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " '\r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " , elementType: '\r\n" + - " \r\n" + - " '\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " , method: '\r\n" + - " \r\n" + - " '\r\n" + - " \r\n" + - " \r\n" + - " , \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " : \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " , '\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " ': '\r\n" + - " \r\n" + - " '\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " '': { type: , elementType: }\r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " , actions: { \r\n" + - " \r\n" + - " \r\n" + - " ,\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " }\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " true\r\n" + - " \r\n" + - " '': { '$':\r\n" + - " , \r\n" + - " \r\n" + - " '$':\r\n" + - " , \r\n" + - " \r\n" + - " }\r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " 'Array'\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " ''\r\n" + - " \r\n" + - " \r\n" + - " ''\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " ''\r\n" + - " \r\n" + - " \r\n" + - " ''\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " $data.ConcurrencyMode.\r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " true\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " true \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " Number.POSITIVE_INFINITY\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " true''\r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " ''\r\n" + - " ''\r\n" + - " \r\n" + - " '$$unbound'\r\n" + - " \r\n" + - " ''\r\n" + - " \r\n" + - " \r\n" + - " ''\r\n" + - " \r\n" + - " \r\n" + - " ''\r\n" + - " \r\n" + - " \r\n" + - " '$$unbound'\r\n" + - " Warning: inverseProperty other side missing: \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " ''\r\n" + - " true\r\n" + - " \r\n" + - " \r\n" + - " ''\r\n" + - " \r\n" + - " \r\n" + - " '$$unbound'\r\n" + - " \r\n" + - " Warning: inverseProperty other side missing: \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - "\r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " Warning: .: is an unknown/unprocessed attribued\r\n" + - " \r\n" + - " \r\n" + - "\r\n" - } - -}); - -$data.MetadataLoader = new $data.MetadataLoaderClass(); -$data.service = function (serviceUri, config, cb) { - var _url, _config, _callback; - function getParam(paramValue) { - switch (typeof paramValue) { - case 'object': - if (typeof paramValue.success === 'function' || typeof paramValue.error === 'function') { - _callback = paramValue; - } else { - _config = paramValue; - } - break; - case 'function': - _callback = paramValue; - break; - default: - break; - } - } - getParam(config); - getParam(cb); - - if (typeof serviceUri === 'object') { - _config = $data.typeSystem.extend(serviceUri, _config); - serviceUri = serviceUri.url; - delete _config.url; - } - - var pHandler = new $data.PromiseHandler(); - _callback = pHandler.createCallback(_callback); - - $data.MetadataLoader.load(serviceUri, { - success: function (factory) { - var type = factory.type; - //register to local store - if (_config) { - var storeAlias = _config.serviceName || _config.storeAlias; - if (storeAlias && 'addStore' in $data) { - $data.addStore(storeAlias, factory, _config.isDefault === undefined || _config.isDefault) - } - } - - _callback.success(factory, type); - }, - error: _callback.error - }, _config); - - return pHandler.getPromise(); -}; -(function ($data) { - if (typeof jQuery !== 'undefined') { - $data.Class.define('$data.Deferred', $data.PromiseHandlerBase, null, { - constructor: function () { - this.deferred = new $.Deferred(); - }, - deferred: {}, - createCallback: function (callBack) { - callBack = $data.typeSystem.createCallbackSetting(callBack); - var self = this; - - return cbWrapper = { - success: function () { - callBack.success.apply(self.deferred, arguments); - self.deferred.resolve.apply(self.deferred, arguments); - }, - error: function () { - Array.prototype.push.call(arguments, self.deferred); - callBack.error.apply(self.deferred, arguments); - }, - notify: function () { - callBack.notify.apply(self.deferred, arguments); - self.deferred.notify.apply(self.deferred, arguments); - } - }; - }, - getPromise: function () { - return this.deferred.promise(); - } - }, null); - - $data.PromiseHandler = $data.Deferred; - } -})($data); -(function ($data) { - - $data.initService = function (apiKey, options) { - var d = new $data.PromiseHandler(); - var cfg; - - if (typeof apiKey === 'object') { - //appId, serviceName, ownerid, isSSL, port, license, url - cfg = apiKey; - var protocol = cfg.isSSL || cfg.isSSL === undefined ? 'https' : 'http'; - var port = cfg.port ? (':' + cfg.port) : ''; - - if (typeof cfg.license === 'string' && cfg.license.toLowerCase() === 'business') { - if (cfg.appId && cfg.serviceName) { - apiKey = protocol + '://' + cfg.appId + '.jaystack.net' + port + '/' + cfg.serviceName; - } else { - apiKey = cfg.url; - } - } else { - if (cfg.ownerId && cfg.appId && cfg.serviceName) { - apiKey = protocol + '://open.jaystack.net/' + cfg.ownerId + '/' + cfg.appId + '/api/' + cfg.serviceName; - } else { - apiKey = cfg.url; - } - } - - delete cfg.url; - cfg = $data.typeSystem.extend(cfg, options); - } else { - cfg = options; - } - - $data.service(apiKey, cfg).then(function (factory) { - var ctx = factory(); - return ctx.onReady() - .then(function (context) { - context.serviceFactory = factory; - d.deferred.resolve(context, factory, factory.type); - }).fail(function () { - d.deferred.reject.apply(d.deferred, arguments); - }); - }).fail(function(){ - d.deferred.reject.apply(d.deferred, arguments); - }); - - return d.getPromise(); - }; - -})($data); diff --git a/release/jaydata.js b/release/jaydata.js deleted file mode 100644 index d904da39..00000000 --- a/release/jaydata.js +++ /dev/null @@ -1,17273 +0,0 @@ -// JayData 1.3.6 -// Dual licensed under MIT and GPL v2 -// Copyright JayStack Technologies (http://jaydata.org/licensing) -// -// JayData is a standards-based, cross-platform Javascript library and a set of -// practices to access and manipulate data from various online and offline sources. -// -// Credits: -// Hajnalka Battancs, Dániel József, János Roden, László Horváth, Péter Nochta -// Péter Zentai, Róbert Bónay, Szabolcs Czinege, Viktor Borza, Viktor Lázár, -// Zoltán Gyebrovszki, Gábor Dolla -// -// More info: http://jaydata.org -// Acorn is a tiny, fast JavaScript parser written in JavaScript. -// -// Acorn was written by Marijn Haverbeke and released under an MIT -// license. The Unicode regexps (for identifiers and whitespace) were -// taken from [Esprima](http://esprima.org) by Ariya Hidayat. -// -// Git repositories for Acorn are available at -// -// http://marijnhaverbeke.nl/git/acorn -// https://github.com/marijnh/acorn.git -// -// Please use the [github bug tracker][ghbt] to report issues. -// -// [ghbt]: https://github.com/marijnh/acorn/issues -// -// This file defines the main parser interface. The library also comes -// with a [error-tolerant parser][dammit] and an -// [abstract syntax tree walker][walk], defined in other files. -// -// [dammit]: acorn_loose.js -// [walk]: util/walk.js - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") return mod(exports); // CommonJS - if (typeof define == "function" && define.amd) return define(["exports"], mod); // AMD - mod(self.acorn || (self.acorn = {})); // Plain browser env -})(function(exports) { - "use strict"; - - exports.version = "0.1.01"; - - // The main exported interface (under `self.acorn` when in the - // browser) is a `parse` function that takes a code string and - // returns an abstract syntax tree as specified by [Mozilla parser - // API][api], with the caveat that the SpiderMonkey-specific syntax - // (`let`, `yield`, inline XML, etc) is not recognized. - // - // [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API - - var options, input, inputLen, sourceFile; - - exports.parse = function(inpt, opts) { - input = String(inpt); inputLen = input.length; - setOptions(opts); - initTokenState(); - return parseTopLevel(options.program); - }; - - // A second optional argument can be given to further configure - // the parser process. These options are recognized: - - var defaultOptions = exports.defaultOptions = { - // `ecmaVersion` indicates the ECMAScript version to parse. Must - // be either 3 or 5. This - // influences support for strict mode, the set of reserved words, and - // support for getters and setter. - ecmaVersion: 5, - // Turn on `strictSemicolons` to prevent the parser from doing - // automatic semicolon insertion. - strictSemicolons: false, - // When `allowTrailingCommas` is false, the parser will not allow - // trailing commas in array and object literals. - allowTrailingCommas: true, - // By default, reserved words are not enforced. Enable - // `forbidReserved` to enforce them. - forbidReserved: false, - // When `locations` is on, `loc` properties holding objects with - // `start` and `end` properties in `{line, column}` form (with - // line being 1-based and column 0-based) will be attached to the - // nodes. - locations: false, - // A function can be passed as `onComment` option, which will - // cause Acorn to call that function with `(block, text, start, - // end)` parameters whenever a comment is skipped. `block` is a - // boolean indicating whether this is a block (`/* */`) comment, - // `text` is the content of the comment, and `start` and `end` are - // character offsets that denote the start and end of the comment. - // When the `locations` option is on, two more parameters are - // passed, the full `{line, column}` locations of the start and - // end of the comments. - onComment: null, - // Nodes have their start and end characters offsets recorded in - // `start` and `end` properties (directly on the node, rather than - // the `loc` object, which holds line/column data. To also add a - // [semi-standardized][range] `range` property holding a `[start, - // end]` array with the same numbers, set the `ranges` option to - // `true`. - // - // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678 - ranges: false, - // It is possible to parse multiple files into a single AST by - // passing the tree produced by parsing the first file as - // `program` option in subsequent parses. This will add the - // toplevel forms of the parsed file to the `Program` (top) node - // of an existing parse tree. - program: null, - // When `location` is on, you can pass this to record the source - // file in every node's `loc` object. - sourceFile: null - }; - - function setOptions(opts) { - options = opts || {}; - for (var opt in defaultOptions) if (!options.hasOwnProperty(opt)) - options[opt] = defaultOptions[opt]; - sourceFile = options.sourceFile || null; - } - - // The `getLineInfo` function is mostly useful when the - // `locations` option is off (for performance reasons) and you - // want to find the line/column position for a given character - // offset. `input` should be the code string that the offset refers - // into. - - var getLineInfo = exports.getLineInfo = function(input, offset) { - for (var line = 1, cur = 0;;) { - lineBreak.lastIndex = cur; - var match = lineBreak.exec(input); - if (match && match.index < offset) { - ++line; - cur = match.index + match[0].length; - } else break; - } - return {line: line, column: offset - cur}; - }; - - // Acorn is organized as a tokenizer and a recursive-descent parser. - // The `tokenize` export provides an interface to the tokenizer. - // Because the tokenizer is optimized for being efficiently used by - // the Acorn parser itself, this interface is somewhat crude and not - // very modular. Performing another parse or call to `tokenize` will - // reset the internal state, and invalidate existing tokenizers. - - exports.tokenize = function(inpt, opts) { - input = String(inpt); inputLen = input.length; - setOptions(opts); - initTokenState(); - - var t = {}; - function getToken(forceRegexp) { - readToken(forceRegexp); - t.start = tokStart; t.end = tokEnd; - t.startLoc = tokStartLoc; t.endLoc = tokEndLoc; - t.type = tokType; t.value = tokVal; - return t; - } - getToken.jumpTo = function(pos, reAllowed) { - tokPos = pos; - if (options.locations) { - tokCurLine = tokLineStart = lineBreak.lastIndex = 0; - var match; - while ((match = lineBreak.exec(input)) && match.index < pos) { - ++tokCurLine; - tokLineStart = match.index + match[0].length; - } - } - var ch = input.charAt(pos - 1); - tokRegexpAllowed = reAllowed; - skipSpace(); - }; - return getToken; - }; - - // State is kept in (closure-)global variables. We already saw the - // `options`, `input`, and `inputLen` variables above. - - // The current position of the tokenizer in the input. - - var tokPos; - - // The start and end offsets of the current token. - - var tokStart, tokEnd; - - // When `options.locations` is true, these hold objects - // containing the tokens start and end line/column pairs. - - var tokStartLoc, tokEndLoc; - - // The type and value of the current token. Token types are objects, - // named by variables against which they can be compared, and - // holding properties that describe them (indicating, for example, - // the precedence of an infix operator, and the original name of a - // keyword token). The kind of value that's held in `tokVal` depends - // on the type of the token. For literals, it is the literal value, - // for operators, the operator name, and so on. - - var tokType, tokVal; - - // Interal state for the tokenizer. To distinguish between division - // operators and regular expressions, it remembers whether the last - // token was one that is allowed to be followed by an expression. - // (If it is, a slash is probably a regexp, if it isn't it's a - // division operator. See the `parseStatement` function for a - // caveat.) - - var tokRegexpAllowed; - - // When `options.locations` is true, these are used to keep - // track of the current line, and know when a new line has been - // entered. - - var tokCurLine, tokLineStart; - - // These store the position of the previous token, which is useful - // when finishing a node and assigning its `end` position. - - var lastStart, lastEnd, lastEndLoc; - - // This is the parser's state. `inFunction` is used to reject - // `return` statements outside of functions, `labels` to verify that - // `break` and `continue` have somewhere to jump to, and `strict` - // indicates whether strict mode is on. - - var inFunction, labels, strict; - - // This function is used to raise exceptions on parse errors. It - // takes an offset integer (into the current `input`) to indicate - // the location of the error, attaches the position to the end - // of the error message, and then raises a `SyntaxError` with that - // message. - - function raise(pos, message) { - var loc = getLineInfo(input, pos); - message += " (" + loc.line + ":" + loc.column + ")"; - var err = new SyntaxError(message); - err.pos = pos; err.loc = loc; err.raisedAt = tokPos; - throw err; - } - - // ## Token types - - // The assignment of fine-grained, information-carrying type objects - // allows the tokenizer to store the information it has about a - // token in a way that is very cheap for the parser to look up. - - // All token type variables start with an underscore, to make them - // easy to recognize. - - // These are the general types. The `type` property is only used to - // make them recognizeable when debugging. - - var _num = {type: "num"}, _regexp = {type: "regexp"}, _string = {type: "string"}; - var _name = {type: "name"}, _eof = {type: "eof"}; - - // Keyword tokens. The `keyword` property (also used in keyword-like - // operators) indicates that the token originated from an - // identifier-like word, which is used when parsing property names. - // - // The `beforeExpr` property is used to disambiguate between regular - // expressions and divisions. It is set on all token types that can - // be followed by an expression (thus, a slash after them would be a - // regular expression). - // - // `isLoop` marks a keyword as starting a loop, which is important - // to know when parsing a label, in order to allow or disallow - // continue jumps to that label. - - var _break = {keyword: "break"}, _case = {keyword: "case", beforeExpr: true}, _catch = {keyword: "catch"}; - var _continue = {keyword: "continue"}, _debugger = {keyword: "debugger"}, _default = {keyword: "default"}; - var _do = {keyword: "do", isLoop: true}, _else = {keyword: "else", beforeExpr: true}; - var _finally = {keyword: "finally"}, _for = {keyword: "for", isLoop: true}, _function = {keyword: "function"}; - var _if = {keyword: "if"}, _return = {keyword: "return", beforeExpr: true}, _switch = {keyword: "switch"}; - var _throw = {keyword: "throw", beforeExpr: true}, _try = {keyword: "try"}, _var = {keyword: "var"}; - var _while = {keyword: "while", isLoop: true}, _with = {keyword: "with"}, _new = {keyword: "new", beforeExpr: true}; - var _this = {keyword: "this"}; - - // The keywords that denote values. - - var _null = {keyword: "null", atomValue: null}, _true = {keyword: "true", atomValue: true}; - var _false = {keyword: "false", atomValue: false}; - - // Some keywords are treated as regular operators. `in` sometimes - // (when parsing `for`) needs to be tested against specifically, so - // we assign a variable name to it for quick comparing. - - var _in = {keyword: "in", binop: 7, beforeExpr: true}; - - // Map keyword names to token types. - - var keywordTypes = {"break": _break, "case": _case, "catch": _catch, - "continue": _continue, "debugger": _debugger, "default": _default, - "do": _do, "else": _else, "finally": _finally, "for": _for, - "function": _function, "if": _if, "return": _return, "switch": _switch, - "throw": _throw, "try": _try, "var": _var, "while": _while, "with": _with, - "null": _null, "true": _true, "false": _false, "new": _new, "in": _in, - "instanceof": {keyword: "instanceof", binop: 7, beforeExpr: true}, "this": _this, - "typeof": {keyword: "typeof", prefix: true, beforeExpr: true}, - "void": {keyword: "void", prefix: true, beforeExpr: true}, - "delete": {keyword: "delete", prefix: true, beforeExpr: true}}; - - // Punctuation token types. Again, the `type` property is purely for debugging. - - var _bracketL = {type: "[", beforeExpr: true}, _bracketR = {type: "]"}, _braceL = {type: "{", beforeExpr: true}; - var _braceR = {type: "}"}, _parenL = {type: "(", beforeExpr: true}, _parenR = {type: ")"}; - var _comma = {type: ",", beforeExpr: true}, _semi = {type: ";", beforeExpr: true}; - var _colon = {type: ":", beforeExpr: true}, _dot = {type: "."}, _question = {type: "?", beforeExpr: true}; - - // Operators. These carry several kinds of properties to help the - // parser use them properly (the presence of these properties is - // what categorizes them as operators). - // - // `binop`, when present, specifies that this operator is a binary - // operator, and will refer to its precedence. - // - // `prefix` and `postfix` mark the operator as a prefix or postfix - // unary operator. `isUpdate` specifies that the node produced by - // the operator should be of type UpdateExpression rather than - // simply UnaryExpression (`++` and `--`). - // - // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as - // binary operators with a very low precedence, that should result - // in AssignmentExpression nodes. - - var _slash = {binop: 10, beforeExpr: true}, _eq = {isAssign: true, beforeExpr: true}; - var _assign = {isAssign: true, beforeExpr: true}, _plusmin = {binop: 9, prefix: true, beforeExpr: true}; - var _incdec = {postfix: true, prefix: true, isUpdate: true}, _prefix = {prefix: true, beforeExpr: true}; - var _bin1 = {binop: 1, beforeExpr: true}, _bin2 = {binop: 2, beforeExpr: true}; - var _bin3 = {binop: 3, beforeExpr: true}, _bin4 = {binop: 4, beforeExpr: true}; - var _bin5 = {binop: 5, beforeExpr: true}, _bin6 = {binop: 6, beforeExpr: true}; - var _bin7 = {binop: 7, beforeExpr: true}, _bin8 = {binop: 8, beforeExpr: true}; - var _bin10 = {binop: 10, beforeExpr: true}; - - // Provide access to the token types for external users of the - // tokenizer. - - exports.tokTypes = {bracketL: _bracketL, bracketR: _bracketR, braceL: _braceL, braceR: _braceR, - parenL: _parenL, parenR: _parenR, comma: _comma, semi: _semi, colon: _colon, - dot: _dot, question: _question, slash: _slash, eq: _eq, name: _name, eof: _eof, - num: _num, regexp: _regexp, string: _string}; - for (var kw in keywordTypes) exports.tokTypes[kw] = keywordTypes[kw]; - - // This is a trick taken from Esprima. It turns out that, on - // non-Chrome browsers, to check whether a string is in a set, a - // predicate containing a big ugly `switch` statement is faster than - // a regular expression, and on Chrome the two are about on par. - // This function uses `eval` (non-lexical) to produce such a - // predicate from a space-separated string of words. - // - // It starts by sorting the words by length. - - function makePredicate(words) { - words = words.split(" "); - var f = "", cats = []; - out: for (var i = 0; i < words.length; ++i) { - for (var j = 0; j < cats.length; ++j) - if (cats[j][0].length == words[i].length) { - cats[j].push(words[i]); - continue out; - } - cats.push([words[i]]); - } - function compareTo(arr) { - if (arr.length == 1) return f += "return str === " + JSON.stringify(arr[0]) + ";"; - f += "switch(str){"; - for (var i = 0; i < arr.length; ++i) f += "case " + JSON.stringify(arr[i]) + ":"; - f += "return true}return false;"; - } - - // When there are more than three length categories, an outer - // switch first dispatches on the lengths, to save on comparisons. - - if (cats.length > 3) { - cats.sort(function(a, b) {return b.length - a.length;}); - f += "switch(str.length){"; - for (var i = 0; i < cats.length; ++i) { - var cat = cats[i]; - f += "case " + cat[0].length + ":"; - compareTo(cat); - } - f += "}"; - - // Otherwise, simply generate a flat `switch` statement. - - } else { - compareTo(words); - } - return new Function("str", f); - } - - // The ECMAScript 3 reserved word list. - - var isReservedWord3 = makePredicate("abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile"); - - // ECMAScript 5 reserved words. - - var isReservedWord5 = makePredicate("class enum extends super const export import"); - - // The additional reserved words in strict mode. - - var isStrictReservedWord = makePredicate("implements interface let package private protected public static yield"); - - // The forbidden variable names in strict mode. - - var isStrictBadIdWord = makePredicate("eval arguments"); - - // And the keywords. - - var isKeyword = makePredicate("break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this"); - - // ## Character categories - - // Big ugly regular expressions that match characters in the - // whitespace, identifier, and identifier-start categories. These - // are only applied when a character is found to actually have a - // code point above 128. - - var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]/; - var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; - var nonASCIIidentifierChars = "\u0371-\u0374\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u0620-\u0649\u0672-\u06d3\u06e7-\u06e8\u06fb-\u06fc\u0730-\u074a\u0800-\u0814\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0840-\u0857\u08e4-\u08fe\u0900-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962-\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09d7\u09df-\u09e0\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2-\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b5f-\u0b60\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62-\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2-\u0ce3\u0ce6-\u0cef\u0d02\u0d03\u0d46-\u0d48\u0d57\u0d62-\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e34-\u0e3a\u0e40-\u0e45\u0e50-\u0e59\u0eb4-\u0eb9\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f41-\u0f47\u0f71-\u0f84\u0f86-\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u1029\u1040-\u1049\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u170e-\u1710\u1720-\u1730\u1740-\u1750\u1772\u1773\u1780-\u17b2\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u1920-\u192b\u1930-\u193b\u1951-\u196d\u19b0-\u19c0\u19c8-\u19c9\u19d0-\u19d9\u1a00-\u1a15\u1a20-\u1a53\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1b46-\u1b4b\u1b50-\u1b59\u1b6b-\u1b73\u1bb0-\u1bb9\u1be6-\u1bf3\u1c00-\u1c22\u1c40-\u1c49\u1c5b-\u1c7d\u1cd0-\u1cd2\u1d00-\u1dbe\u1e01-\u1f15\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2d81-\u2d96\u2de0-\u2dff\u3021-\u3028\u3099\u309a\ua640-\ua66d\ua674-\ua67d\ua69f\ua6f0-\ua6f1\ua7f8-\ua800\ua806\ua80b\ua823-\ua827\ua880-\ua881\ua8b4-\ua8c4\ua8d0-\ua8d9\ua8f3-\ua8f7\ua900-\ua909\ua926-\ua92d\ua930-\ua945\ua980-\ua983\ua9b3-\ua9c0\uaa00-\uaa27\uaa40-\uaa41\uaa4c-\uaa4d\uaa50-\uaa59\uaa7b\uaae0-\uaae9\uaaf2-\uaaf3\uabc0-\uabe1\uabec\uabed\uabf0-\uabf9\ufb20-\ufb28\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"; - var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); - var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); - - // Whether a single character denotes a newline. - - var newline = /[\n\r\u2028\u2029]/; - - // Matches a whole line break (where CRLF is considered a single - // line break). Used to count lines. - - var lineBreak = /\r\n|[\n\r\u2028\u2029]/g; - - // Test whether a given character code starts an identifier. - - function isIdentifierStart(code) { - if (code < 65) return code === 36; - if (code < 91) return true; - if (code < 97) return code === 95; - if (code < 123)return true; - return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)); - } - - // Test whether a given character is part of an identifier. - - function isIdentifierChar(code) { - if (code < 48) return code === 36; - if (code < 58) return true; - if (code < 65) return false; - if (code < 91) return true; - if (code < 97) return code === 95; - if (code < 123)return true; - return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)); - } - - // ## Tokenizer - - // These are used when `options.locations` is on, for the - // `tokStartLoc` and `tokEndLoc` properties. - - function line_loc_t() { - this.line = tokCurLine; - this.column = tokPos - tokLineStart; - } - - // Reset the token state. Used at the start of a parse. - - function initTokenState() { - tokCurLine = 1; - tokPos = tokLineStart = 0; - tokRegexpAllowed = true; - skipSpace(); - } - - // Called at the end of every token. Sets `tokEnd`, `tokVal`, and - // `tokRegexpAllowed`, and skips the space after the token, so that - // the next one's `tokStart` will point at the right position. - - function finishToken(type, val) { - tokEnd = tokPos; - if (options.locations) tokEndLoc = new line_loc_t; - tokType = type; - skipSpace(); - tokVal = val; - tokRegexpAllowed = type.beforeExpr; - } - - function skipBlockComment() { - var startLoc = options.onComment && options.locations && new line_loc_t; - var start = tokPos, end = input.indexOf("*/", tokPos += 2); - if (end === -1) raise(tokPos - 2, "Unterminated comment"); - tokPos = end + 2; - if (options.locations) { - lineBreak.lastIndex = start; - var match; - while ((match = lineBreak.exec(input)) && match.index < tokPos) { - ++tokCurLine; - tokLineStart = match.index + match[0].length; - } - } - if (options.onComment) - options.onComment(true, input.slice(start + 2, end), start, tokPos, - startLoc, options.locations && new line_loc_t); - } - - function skipLineComment() { - var start = tokPos; - var startLoc = options.onComment && options.locations && new line_loc_t; - var ch = input.charCodeAt(tokPos+=2); - while (tokPos < inputLen && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8329) { - ++tokPos; - ch = input.charCodeAt(tokPos); - } - if (options.onComment) - options.onComment(false, input.slice(start + 2, tokPos), start, tokPos, - startLoc, options.locations && new line_loc_t); - } - - // Called at the start of the parse and after every token. Skips - // whitespace and comments, and. - - function skipSpace() { - while (tokPos < inputLen) { - var ch = input.charCodeAt(tokPos); - if (ch === 32) { // ' ' - ++tokPos; - } else if(ch === 13) { - ++tokPos; - var next = input.charCodeAt(tokPos); - if(next === 10) { - ++tokPos; - } - if(options.locations) { - ++tokCurLine; - tokLineStart = tokPos; - } - } else if (ch === 10) { - ++tokPos; - ++tokCurLine; - tokLineStart = tokPos; - } else if(ch < 14 && ch > 8) { - ++tokPos; - } else if (ch === 47) { // '/' - var next = input.charCodeAt(tokPos+1); - if (next === 42) { // '*' - skipBlockComment(); - } else if (next === 47) { // '/' - skipLineComment(); - } else break; - } else if ((ch < 14 && ch > 8) || ch === 32 || ch === 160) { // ' ', '\xa0' - ++tokPos; - } else if (ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) { - ++tokPos; - } else { - break; - } - } - } - - // ### Token reading - - // This is the function that is called to fetch the next token. It - // is somewhat obscure, because it works in character codes rather - // than characters, and because operator parsing has been inlined - // into it. - // - // All in the name of speed. - // - // The `forceRegexp` parameter is used in the one case where the - // `tokRegexpAllowed` trick does not work. See `parseStatement`. - - function readToken_dot() { - var next = input.charCodeAt(tokPos+1); - if (next >= 48 && next <= 57) return readNumber(true); - ++tokPos; - return finishToken(_dot); - } - - function readToken_slash() { // '/' - var next = input.charCodeAt(tokPos+1); - if (tokRegexpAllowed) {++tokPos; return readRegexp();} - if (next === 61) return finishOp(_assign, 2); - return finishOp(_slash, 1); - } - - function readToken_mult_modulo() { // '%*' - var next = input.charCodeAt(tokPos+1); - if (next === 61) return finishOp(_assign, 2); - return finishOp(_bin10, 1); - } - - function readToken_pipe_amp(code) { // '|&' - var next = input.charCodeAt(tokPos+1); - if (next === code) return finishOp(code === 124 ? _bin1 : _bin2, 2); - if (next === 61) return finishOp(_assign, 2); - return finishOp(code === 124 ? _bin3 : _bin5, 1); - } - - function readToken_caret() { // '^' - var next = input.charCodeAt(tokPos+1); - if (next === 61) return finishOp(_assign, 2); - return finishOp(_bin4, 1); - } - - function readToken_plus_min(code) { // '+-' - var next = input.charCodeAt(tokPos+1); - if (next === code) return finishOp(_incdec, 2); - if (next === 61) return finishOp(_assign, 2); - return finishOp(_plusmin, 1); - } - - function readToken_lt_gt(code) { // '<>' - var next = input.charCodeAt(tokPos+1); - var size = 1; - if (next === code) { - size = code === 62 && input.charCodeAt(tokPos+2) === 62 ? 3 : 2; - if (input.charCodeAt(tokPos + size) === 61) return finishOp(_assign, size + 1); - return finishOp(_bin8, size); - } - if (next === 61) - size = input.charCodeAt(tokPos+2) === 61 ? 3 : 2; - return finishOp(_bin7, size); - } - - function readToken_eq_excl(code) { // '=!' - var next = input.charCodeAt(tokPos+1); - if (next === 61) return finishOp(_bin6, input.charCodeAt(tokPos+2) === 61 ? 3 : 2); - return finishOp(code === 61 ? _eq : _prefix, 1); - } - - function getTokenFromCode(code) { - switch(code) { - // The interpretation of a dot depends on whether it is followed - // by a digit. - case 46: // '.' - return readToken_dot(); - - // Punctuation tokens. - case 40: ++tokPos; return finishToken(_parenL); - case 41: ++tokPos; return finishToken(_parenR); - case 59: ++tokPos; return finishToken(_semi); - case 44: ++tokPos; return finishToken(_comma); - case 91: ++tokPos; return finishToken(_bracketL); - case 93: ++tokPos; return finishToken(_bracketR); - case 123: ++tokPos; return finishToken(_braceL); - case 125: ++tokPos; return finishToken(_braceR); - case 58: ++tokPos; return finishToken(_colon); - case 63: ++tokPos; return finishToken(_question); - - // '0x' is a hexadecimal number. - case 48: // '0' - var next = input.charCodeAt(tokPos+1); - if (next === 120 || next === 88) return readHexNumber(); - // Anything else beginning with a digit is an integer, octal - // number, or float. - case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: // 1-9 - return readNumber(false); - - // Quotes produce strings. - case 34: case 39: // '"', "'" - return readString(code); - - // Operators are parsed inline in tiny state machines. '=' (61) is - // often referred to. `finishOp` simply skips the amount of - // characters it is given as second argument, and returns a token - // of the type given by its first argument. - - case 47: // '/' - return readToken_slash(code); - - case 37: case 42: // '%*' - return readToken_mult_modulo(); - - case 124: case 38: // '|&' - return readToken_pipe_amp(code); - - case 94: // '^' - return readToken_caret(); - - case 43: case 45: // '+-' - return readToken_plus_min(code); - - case 60: case 62: // '<>' - return readToken_lt_gt(code); - - case 61: case 33: // '=!' - return readToken_eq_excl(code); - - case 126: // '~' - return finishOp(_prefix, 1); - } - - return false; - } - - function readToken(forceRegexp) { - if (!forceRegexp) tokStart = tokPos; - else tokPos = tokStart + 1; - if (options.locations) tokStartLoc = new line_loc_t; - if (forceRegexp) return readRegexp(); - if (tokPos >= inputLen) return finishToken(_eof); - - var code = input.charCodeAt(tokPos); - // Identifier or keyword. '\uXXXX' sequences are allowed in - // identifiers, so '\' also dispatches to that. - if (isIdentifierStart(code) || code === 92 /* '\' */) return readWord(); - - var tok = getTokenFromCode(code); - - if (tok === false) { - // If we are here, we either found a non-ASCII identifier - // character, or something that's entirely disallowed. - var ch = String.fromCharCode(code); - if (ch === "\\" || nonASCIIidentifierStart.test(ch)) return readWord(); - raise(tokPos, "Unexpected character '" + ch + "'"); - } - return tok; - } - - function finishOp(type, size) { - var str = input.slice(tokPos, tokPos + size); - tokPos += size; - finishToken(type, str); - } - - // Parse a regular expression. Some context-awareness is necessary, - // since a '/' inside a '[]' set does not end the expression. - - function readRegexp() { - var content = "", escaped, inClass, start = tokPos; - for (;;) { - if (tokPos >= inputLen) raise(start, "Unterminated regular expression"); - var ch = input.charAt(tokPos); - if (newline.test(ch)) raise(start, "Unterminated regular expression"); - if (!escaped) { - if (ch === "[") inClass = true; - else if (ch === "]" && inClass) inClass = false; - else if (ch === "/" && !inClass) break; - escaped = ch === "\\"; - } else escaped = false; - ++tokPos; - } - var content = input.slice(start, tokPos); - ++tokPos; - // Need to use `readWord1` because '\uXXXX' sequences are allowed - // here (don't ask). - var mods = readWord1(); - if (mods && !/^[gmsiy]*$/.test(mods)) raise(start, "Invalid regexp flag"); - return finishToken(_regexp, new RegExp(content, mods)); - } - - // Read an integer in the given radix. Return null if zero digits - // were read, the integer value otherwise. When `len` is given, this - // will return `null` unless the integer has exactly `len` digits. - - function readInt(radix, len) { - var start = tokPos, total = 0; - for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) { - var code = input.charCodeAt(tokPos), val; - if (code >= 97) val = code - 97 + 10; // a - else if (code >= 65) val = code - 65 + 10; // A - else if (code >= 48 && code <= 57) val = code - 48; // 0-9 - else val = Infinity; - if (val >= radix) break; - ++tokPos; - total = total * radix + val; - } - if (tokPos === start || len != null && tokPos - start !== len) return null; - - return total; - } - - function readHexNumber() { - tokPos += 2; // 0x - var val = readInt(16); - if (val == null) raise(tokStart + 2, "Expected hexadecimal number"); - if (isIdentifierStart(input.charCodeAt(tokPos))) raise(tokPos, "Identifier directly after number"); - return finishToken(_num, val); - } - - // Read an integer, octal integer, or floating-point number. - - function readNumber(startsWithDot) { - var start = tokPos, isFloat = false, octal = input.charCodeAt(tokPos) === 48; - if (!startsWithDot && readInt(10) === null) raise(start, "Invalid number"); - if (input.charCodeAt(tokPos) === 46) { - ++tokPos; - readInt(10); - isFloat = true; - } - var next = input.charCodeAt(tokPos); - if (next === 69 || next === 101) { // 'eE' - next = input.charCodeAt(++tokPos); - if (next === 43 || next === 45) ++tokPos; // '+-' - if (readInt(10) === null) raise(start, "Invalid number") - isFloat = true; - } - if (isIdentifierStart(input.charCodeAt(tokPos))) raise(tokPos, "Identifier directly after number"); - - var str = input.slice(start, tokPos), val; - if (isFloat) val = parseFloat(str); - else if (!octal || str.length === 1) val = parseInt(str, 10); - else if (/[89]/.test(str) || strict) raise(start, "Invalid number"); - else val = parseInt(str, 8); - return finishToken(_num, val); - } - - // Read a string value, interpreting backslash-escapes. - - function readString(quote) { - tokPos++; - var out = ""; - for (;;) { - if (tokPos >= inputLen) raise(tokStart, "Unterminated string constant"); - var ch = input.charCodeAt(tokPos); - if (ch === quote) { - ++tokPos; - return finishToken(_string, out); - } - if (ch === 92) { // '\' - ch = input.charCodeAt(++tokPos); - var octal = /^[0-7]+/.exec(input.slice(tokPos, tokPos + 3)); - if (octal) octal = octal[0]; - while (octal && parseInt(octal, 8) > 255) octal = octal.slice(0, octal.length - 1); - if (octal === "0") octal = null; - ++tokPos; - if (octal) { - if (strict) raise(tokPos - 2, "Octal literal in strict mode"); - out += String.fromCharCode(parseInt(octal, 8)); - tokPos += octal.length - 1; - } else { - switch (ch) { - case 110: out += "\n"; break; // 'n' -> '\n' - case 114: out += "\r"; break; // 'r' -> '\r' - case 120: out += String.fromCharCode(readHexChar(2)); break; // 'x' - case 117: out += String.fromCharCode(readHexChar(4)); break; // 'u' - case 85: out += String.fromCharCode(readHexChar(8)); break; // 'U' - case 116: out += "\t"; break; // 't' -> '\t' - case 98: out += "\b"; break; // 'b' -> '\b' - case 118: out += "\u000b"; break; // 'v' -> '\u000b' - case 102: out += "\f"; break; // 'f' -> '\f' - case 48: out += "\0"; break; // 0 -> '\0' - case 13: if (input.charCodeAt(tokPos) === 10) ++tokPos; // '\r\n' - case 10: // ' \n' - if (options.locations) { tokLineStart = tokPos; ++tokCurLine; } - break; - default: out += String.fromCharCode(ch); break; - } - } - } else { - if (ch === 13 || ch === 10 || ch === 8232 || ch === 8329) raise(tokStart, "Unterminated string constant"); - out += String.fromCharCode(ch); // '\' - ++tokPos; - } - } - } - - // Used to read character escape sequences ('\x', '\u', '\U'). - - function readHexChar(len) { - var n = readInt(16, len); - if (n === null) raise(tokStart, "Bad character escape sequence"); - return n; - } - - // Used to signal to callers of `readWord1` whether the word - // contained any escape sequences. This is needed because words with - // escape sequences must not be interpreted as keywords. - - var containsEsc; - - // Read an identifier, and return it as a string. Sets `containsEsc` - // to whether the word contained a '\u' escape. - // - // Only builds up the word character-by-character when it actually - // containeds an escape, as a micro-optimization. - - function readWord1() { - containsEsc = false; - var word, first = true, start = tokPos; - for (;;) { - var ch = input.charCodeAt(tokPos); - if (isIdentifierChar(ch)) { - if (containsEsc) word += input.charAt(tokPos); - ++tokPos; - } else if (ch === 92) { // "\" - if (!containsEsc) word = input.slice(start, tokPos); - containsEsc = true; - if (input.charCodeAt(++tokPos) != 117) // "u" - raise(tokPos, "Expecting Unicode escape sequence \\uXXXX"); - ++tokPos; - var esc = readHexChar(4); - var escStr = String.fromCharCode(esc); - if (!escStr) raise(tokPos - 1, "Invalid Unicode escape"); - if (!(first ? isIdentifierStart(esc) : isIdentifierChar(esc))) - raise(tokPos - 4, "Invalid Unicode escape"); - word += escStr; - } else { - break; - } - first = false; - } - return containsEsc ? word : input.slice(start, tokPos); - } - - // Read an identifier or keyword token. Will check for reserved - // words when necessary. - - function readWord() { - var word = readWord1(); - var type = _name; - if (!containsEsc) { - if (isKeyword(word)) type = keywordTypes[word]; - else if (options.forbidReserved && - (options.ecmaVersion === 3 ? isReservedWord3 : isReservedWord5)(word) || - strict && isStrictReservedWord(word)) - raise(tokStart, "The keyword '" + word + "' is reserved"); - } - return finishToken(type, word); - } - - // ## Parser - - // A recursive descent parser operates by defining functions for all - // syntactic elements, and recursively calling those, each function - // advancing the input stream and returning an AST node. Precedence - // of constructs (for example, the fact that `!x[1]` means `!(x[1])` - // instead of `(!x)[1]` is handled by the fact that the parser - // function that parses unary prefix operators is called first, and - // in turn calls the function that parses `[]` subscripts — that - // way, it'll receive the node for `x[1]` already parsed, and wraps - // *that* in the unary operator node. - // - // Acorn uses an [operator precedence parser][opp] to handle binary - // operator precedence, because it is much more compact than using - // the technique outlined above, which uses different, nesting - // functions to specify precedence, for all of the ten binary - // precedence levels that JavaScript defines. - // - // [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser - - // ### Parser utilities - - // Continue to the next token. - - function next() { - lastStart = tokStart; - lastEnd = tokEnd; - lastEndLoc = tokEndLoc; - readToken(); - } - - // Enter strict mode. Re-reads the next token to please pedantic - // tests ("use strict"; 010; -- should fail). - - function setStrict(strct) { - strict = strct; - tokPos = lastEnd; - while (tokPos < tokLineStart) { - tokLineStart = input.lastIndexOf("\n", tokLineStart - 2) + 1; - --tokCurLine; - } - skipSpace(); - readToken(); - } - - // Start an AST node, attaching a start offset. - - function node_t() { - this.type = null; - this.start = tokStart; - this.end = null; - } - - function node_loc_t() { - this.start = tokStartLoc; - this.end = null; - if (sourceFile !== null) this.source = sourceFile; - } - - function startNode() { - var node = new node_t(); - if (options.locations) - node.loc = new node_loc_t(); - if (options.ranges) - node.range = [tokStart, 0]; - return node; - } - - // Start a node whose start offset information should be based on - // the start of another node. For example, a binary operator node is - // only started after its left-hand side has already been parsed. - - function startNodeFrom(other) { - var node = new node_t(); - node.start = other.start; - if (options.locations) { - node.loc = new node_loc_t(); - node.loc.start = other.loc.start; - } - if (options.ranges) - node.range = [other.range[0], 0]; - - return node; - } - - // Finish an AST node, adding `type` and `end` properties. - - function finishNode(node, type) { - node.type = type; - node.end = lastEnd; - if (options.locations) - node.loc.end = lastEndLoc; - if (options.ranges) - node.range[1] = lastEnd; - return node; - } - - // Test whether a statement node is the string literal `"use strict"`. - - function isUseStrict(stmt) { - return options.ecmaVersion >= 5 && stmt.type === "ExpressionStatement" && - stmt.expression.type === "Literal" && stmt.expression.value === "use strict"; - } - - // Predicate that tests whether the next token is of the given - // type, and if yes, consumes it as a side effect. - - function eat(type) { - if (tokType === type) { - next(); - return true; - } - } - - // Test whether a semicolon can be inserted at the current position. - - function canInsertSemicolon() { - return !options.strictSemicolons && - (tokType === _eof || tokType === _braceR || newline.test(input.slice(lastEnd, tokStart))); - } - - // Consume a semicolon, or, failing that, see if we are allowed to - // pretend that there is a semicolon at this position. - - function semicolon() { - if (!eat(_semi) && !canInsertSemicolon()) unexpected(); - } - - // Expect a token of a given type. If found, consume it, otherwise, - // raise an unexpected token error. - - function expect(type) { - if (tokType === type) next(); - else unexpected(); - } - - // Raise an unexpected token error. - - function unexpected() { - raise(tokStart, "Unexpected token"); - } - - // Verify that a node is an lval — something that can be assigned - // to. - - function checkLVal(expr) { - if (expr.type !== "Identifier" && expr.type !== "MemberExpression") - raise(expr.start, "Assigning to rvalue"); - if (strict && expr.type === "Identifier" && isStrictBadIdWord(expr.name)) - raise(expr.start, "Assigning to " + expr.name + " in strict mode"); - } - - // ### Statement parsing - - // Parse a program. Initializes the parser, reads any number of - // statements, and wraps them in a Program node. Optionally takes a - // `program` argument. If present, the statements will be appended - // to its body instead of creating a new node. - - function parseTopLevel(program) { - lastStart = lastEnd = tokPos; - if (options.locations) lastEndLoc = new line_loc_t; - inFunction = strict = null; - labels = []; - readToken(); - - var node = program || startNode(), first = true; - if (!program) node.body = []; - while (tokType !== _eof) { - var stmt = parseStatement(); - node.body.push(stmt); - if (first && isUseStrict(stmt)) setStrict(true); - first = false; - } - return finishNode(node, "Program"); - } - - var loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"}; - - // Parse a single statement. - // - // If expecting a statement and finding a slash operator, parse a - // regular expression literal. This is to handle cases like - // `if (foo) /blah/.exec(foo);`, where looking at the previous token - // does not help. - - function parseStatement() { - if (tokType === _slash) - readToken(true); - - var starttype = tokType, node = startNode(); - - // Most types of statements are recognized by the keyword they - // start with. Many are trivial to parse, some require a bit of - // complexity. - - switch (starttype) { - case _break: case _continue: - next(); - var isBreak = starttype === _break; - if (eat(_semi) || canInsertSemicolon()) node.label = null; - else if (tokType !== _name) unexpected(); - else { - node.label = parseIdent(); - semicolon(); - } - - // Verify that there is an actual destination to break or - // continue to. - for (var i = 0; i < labels.length; ++i) { - var lab = labels[i]; - if (node.label == null || lab.name === node.label.name) { - if (lab.kind != null && (isBreak || lab.kind === "loop")) break; - if (node.label && isBreak) break; - } - } - if (i === labels.length) raise(node.start, "Unsyntactic " + starttype.keyword); - return finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement"); - - case _debugger: - next(); - semicolon(); - return finishNode(node, "DebuggerStatement"); - - case _do: - next(); - labels.push(loopLabel); - node.body = parseStatement(); - labels.pop(); - expect(_while); - node.test = parseParenExpression(); - semicolon(); - return finishNode(node, "DoWhileStatement"); - - // Disambiguating between a `for` and a `for`/`in` loop is - // non-trivial. Basically, we have to parse the init `var` - // statement or expression, disallowing the `in` operator (see - // the second parameter to `parseExpression`), and then check - // whether the next token is `in`. When there is no init part - // (semicolon immediately after the opening parenthesis), it is - // a regular `for` loop. - - case _for: - next(); - labels.push(loopLabel); - expect(_parenL); - if (tokType === _semi) return parseFor(node, null); - if (tokType === _var) { - var init = startNode(); - next(); - parseVar(init, true); - if (init.declarations.length === 1 && eat(_in)) - return parseForIn(node, init); - return parseFor(node, init); - } - var init = parseExpression(false, true); - if (eat(_in)) {checkLVal(init); return parseForIn(node, init);} - return parseFor(node, init); - - case _function: - next(); - return parseFunction(node, true); - - case _if: - next(); - node.test = parseParenExpression(); - node.consequent = parseStatement(); - node.alternate = eat(_else) ? parseStatement() : null; - return finishNode(node, "IfStatement"); - - case _return: - if (!inFunction) raise(tokStart, "'return' outside of function"); - next(); - - // In `return` (and `break`/`continue`), the keywords with - // optional arguments, we eagerly look for a semicolon or the - // possibility to insert one. - - if (eat(_semi) || canInsertSemicolon()) node.argument = null; - else { node.argument = parseExpression(); semicolon(); } - return finishNode(node, "ReturnStatement"); - - case _switch: - next(); - node.discriminant = parseParenExpression(); - node.cases = []; - expect(_braceL); - labels.push(switchLabel); - - // Statements under must be grouped (by label) in SwitchCase - // nodes. `cur` is used to keep the node that we are currently - // adding statements to. - - for (var cur, sawDefault; tokType != _braceR;) { - if (tokType === _case || tokType === _default) { - var isCase = tokType === _case; - if (cur) finishNode(cur, "SwitchCase"); - node.cases.push(cur = startNode()); - cur.consequent = []; - next(); - if (isCase) cur.test = parseExpression(); - else { - if (sawDefault) raise(lastStart, "Multiple default clauses"); sawDefault = true; - cur.test = null; - } - expect(_colon); - } else { - if (!cur) unexpected(); - cur.consequent.push(parseStatement()); - } - } - if (cur) finishNode(cur, "SwitchCase"); - next(); // Closing brace - labels.pop(); - return finishNode(node, "SwitchStatement"); - - case _throw: - next(); - if (newline.test(input.slice(lastEnd, tokStart))) - raise(lastEnd, "Illegal newline after throw"); - node.argument = parseExpression(); - semicolon(); - return finishNode(node, "ThrowStatement"); - - case _try: - next(); - node.block = parseBlock(); - node.handler = null; - if (tokType === _catch) { - var clause = startNode(); - next(); - expect(_parenL); - clause.param = parseIdent(); - if (strict && isStrictBadIdWord(clause.param.name)) - raise(clause.param.start, "Binding " + clause.param.name + " in strict mode"); - expect(_parenR); - clause.guard = null; - clause.body = parseBlock(); - node.handler = finishNode(clause, "CatchClause"); - } - node.finalizer = eat(_finally) ? parseBlock() : null; - if (!node.handler && !node.finalizer) - raise(node.start, "Missing catch or finally clause"); - return finishNode(node, "TryStatement"); - - case _var: - next(); - node = parseVar(node); - semicolon(); - return node; - - case _while: - next(); - node.test = parseParenExpression(); - labels.push(loopLabel); - node.body = parseStatement(); - labels.pop(); - return finishNode(node, "WhileStatement"); - - case _with: - if (strict) raise(tokStart, "'with' in strict mode"); - next(); - node.object = parseParenExpression(); - node.body = parseStatement(); - return finishNode(node, "WithStatement"); - - case _braceL: - return parseBlock(); - - case _semi: - next(); - return finishNode(node, "EmptyStatement"); - - // If the statement does not start with a statement keyword or a - // brace, it's an ExpressionStatement or LabeledStatement. We - // simply start parsing an expression, and afterwards, if the - // next token is a colon and the expression was a simple - // Identifier node, we switch to interpreting it as a label. - - default: - var maybeName = tokVal, expr = parseExpression(); - if (starttype === _name && expr.type === "Identifier" && eat(_colon)) { - for (var i = 0; i < labels.length; ++i) - if (labels[i].name === maybeName) raise(expr.start, "Label '" + maybeName + "' is already declared"); - var kind = tokType.isLoop ? "loop" : tokType === _switch ? "switch" : null; - labels.push({name: maybeName, kind: kind}); - node.body = parseStatement(); - labels.pop(); - node.label = expr; - return finishNode(node, "LabeledStatement"); - } else { - node.expression = expr; - semicolon(); - return finishNode(node, "ExpressionStatement"); - } - } - } - - // Used for constructs like `switch` and `if` that insist on - // parentheses around their expression. - - function parseParenExpression() { - expect(_parenL); - var val = parseExpression(); - expect(_parenR); - return val; - } - - // Parse a semicolon-enclosed block of statements, handling `"use - // strict"` declarations when `allowStrict` is true (used for - // function bodies). - - function parseBlock(allowStrict) { - var node = startNode(), first = true, strict = false, oldStrict; - node.body = []; - expect(_braceL); - while (!eat(_braceR)) { - var stmt = parseStatement(); - node.body.push(stmt); - if (first && isUseStrict(stmt)) { - oldStrict = strict; - setStrict(strict = true); - } - first = false - } - if (strict && !oldStrict) setStrict(false); - return finishNode(node, "BlockStatement"); - } - - // Parse a regular `for` loop. The disambiguation code in - // `parseStatement` will already have parsed the init statement or - // expression. - - function parseFor(node, init) { - node.init = init; - expect(_semi); - node.test = tokType === _semi ? null : parseExpression(); - expect(_semi); - node.update = tokType === _parenR ? null : parseExpression(); - expect(_parenR); - node.body = parseStatement(); - labels.pop(); - return finishNode(node, "ForStatement"); - } - - // Parse a `for`/`in` loop. - - function parseForIn(node, init) { - node.left = init; - node.right = parseExpression(); - expect(_parenR); - node.body = parseStatement(); - labels.pop(); - return finishNode(node, "ForInStatement"); - } - - // Parse a list of variable declarations. - - function parseVar(node, noIn) { - node.declarations = []; - node.kind = "var"; - for (;;) { - var decl = startNode(); - decl.id = parseIdent(); - if (strict && isStrictBadIdWord(decl.id.name)) - raise(decl.id.start, "Binding " + decl.id.name + " in strict mode"); - decl.init = eat(_eq) ? parseExpression(true, noIn) : null; - node.declarations.push(finishNode(decl, "VariableDeclarator")); - if (!eat(_comma)) break; - } - return finishNode(node, "VariableDeclaration"); - } - - // ### Expression parsing - - // These nest, from the most general expression type at the top to - // 'atomic', nondivisible expression types at the bottom. Most of - // the functions will simply let the function(s) below them parse, - // and, *if* the syntactic construct they handle is present, wrap - // the AST node that the inner parser gave them in another node. - - // Parse a full expression. The arguments are used to forbid comma - // sequences (in argument lists, array literals, or object literals) - // or the `in` operator (in for loops initalization expressions). - - function parseExpression(noComma, noIn) { - var expr = parseMaybeAssign(noIn); - if (!noComma && tokType === _comma) { - var node = startNodeFrom(expr); - node.expressions = [expr]; - while (eat(_comma)) node.expressions.push(parseMaybeAssign(noIn)); - return finishNode(node, "SequenceExpression"); - } - return expr; - } - - // Parse an assignment expression. This includes applications of - // operators like `+=`. - - function parseMaybeAssign(noIn) { - var left = parseMaybeConditional(noIn); - if (tokType.isAssign) { - var node = startNodeFrom(left); - node.operator = tokVal; - node.left = left; - next(); - node.right = parseMaybeAssign(noIn); - checkLVal(left); - return finishNode(node, "AssignmentExpression"); - } - return left; - } - - // Parse a ternary conditional (`?:`) operator. - - function parseMaybeConditional(noIn) { - var expr = parseExprOps(noIn); - if (eat(_question)) { - var node = startNodeFrom(expr); - node.test = expr; - node.consequent = parseExpression(true); - expect(_colon); - node.alternate = parseExpression(true, noIn); - return finishNode(node, "ConditionalExpression"); - } - return expr; - } - - // Start the precedence parser. - - function parseExprOps(noIn) { - return parseExprOp(parseMaybeUnary(noIn), -1, noIn); - } - - // Parse binary operators with the operator precedence parsing - // algorithm. `left` is the left-hand side of the operator. - // `minPrec` provides context that allows the function to stop and - // defer further parser to one of its callers when it encounters an - // operator that has a lower precedence than the set it is parsing. - - function parseExprOp(left, minPrec, noIn) { - var prec = tokType.binop; - if (prec != null && (!noIn || tokType !== _in)) { - if (prec > minPrec) { - var node = startNodeFrom(left); - node.left = left; - node.operator = tokVal; - next(); - node.right = parseExprOp(parseMaybeUnary(noIn), prec, noIn); - var node = finishNode(node, /&&|\|\|/.test(node.operator) ? "LogicalExpression" : "BinaryExpression"); - return parseExprOp(node, minPrec, noIn); - } - } - return left; - } - - // Parse unary operators, both prefix and postfix. - - function parseMaybeUnary(noIn) { - if (tokType.prefix) { - var node = startNode(), update = tokType.isUpdate; - node.operator = tokVal; - node.prefix = true; - next(); - node.argument = parseMaybeUnary(noIn); - if (update) checkLVal(node.argument); - else if (strict && node.operator === "delete" && - node.argument.type === "Identifier") - raise(node.start, "Deleting local variable in strict mode"); - return finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); - } - var expr = parseExprSubscripts(); - while (tokType.postfix && !canInsertSemicolon()) { - var node = startNodeFrom(expr); - node.operator = tokVal; - node.prefix = false; - node.argument = expr; - checkLVal(expr); - next(); - expr = finishNode(node, "UpdateExpression"); - } - return expr; - } - - // Parse call, dot, and `[]`-subscript expressions. - - function parseExprSubscripts() { - return parseSubscripts(parseExprAtom()); - } - - function parseSubscripts(base, noCalls) { - if (eat(_dot)) { - var node = startNodeFrom(base); - node.object = base; - node.property = parseIdent(true); - node.computed = false; - return parseSubscripts(finishNode(node, "MemberExpression"), noCalls); - } else if (eat(_bracketL)) { - var node = startNodeFrom(base); - node.object = base; - node.property = parseExpression(); - node.computed = true; - expect(_bracketR); - return parseSubscripts(finishNode(node, "MemberExpression"), noCalls); - } else if (!noCalls && eat(_parenL)) { - var node = startNodeFrom(base); - node.callee = base; - node.arguments = parseExprList(_parenR, false); - return parseSubscripts(finishNode(node, "CallExpression"), noCalls); - } else return base; - } - - // Parse an atomic expression — either a single token that is an - // expression, an expression started by a keyword like `function` or - // `new`, or an expression wrapped in punctuation like `()`, `[]`, - // or `{}`. - - function parseExprAtom() { - switch (tokType) { - case _this: - var node = startNode(); - next(); - return finishNode(node, "ThisExpression"); - case _name: - return parseIdent(); - case _num: case _string: case _regexp: - var node = startNode(); - node.value = tokVal; - node.raw = input.slice(tokStart, tokEnd); - next(); - return finishNode(node, "Literal"); - - case _null: case _true: case _false: - var node = startNode(); - node.value = tokType.atomValue; - node.raw = tokType.keyword - next(); - return finishNode(node, "Literal"); - - case _parenL: - var tokStartLoc1 = tokStartLoc, tokStart1 = tokStart; - next(); - var val = parseExpression(); - val.start = tokStart1; - val.end = tokEnd; - if (options.locations) { - val.loc.start = tokStartLoc1; - val.loc.end = tokEndLoc; - } - if (options.ranges) - val.range = [tokStart1, tokEnd]; - expect(_parenR); - return val; - - case _bracketL: - var node = startNode(); - next(); - node.elements = parseExprList(_bracketR, true, true); - return finishNode(node, "ArrayExpression"); - - case _braceL: - return parseObj(); - - case _function: - var node = startNode(); - next(); - return parseFunction(node, false); - - case _new: - return parseNew(); - - default: - unexpected(); - } - } - - // New's precedence is slightly tricky. It must allow its argument - // to be a `[]` or dot subscript expression, but not a call — at - // least, not without wrapping it in parentheses. Thus, it uses the - - function parseNew() { - var node = startNode(); - next(); - node.callee = parseSubscripts(parseExprAtom(), true); - if (eat(_parenL)) node.arguments = parseExprList(_parenR, false); - else node.arguments = []; - return finishNode(node, "NewExpression"); - } - - // Parse an object literal. - - function parseObj() { - var node = startNode(), first = true, sawGetSet = false; - node.properties = []; - next(); - while (!eat(_braceR)) { - if (!first) { - expect(_comma); - if (options.allowTrailingCommas && eat(_braceR)) break; - } else first = false; - - var prop = {key: parsePropertyName()}, isGetSet = false, kind; - if (eat(_colon)) { - prop.value = parseExpression(true); - kind = prop.kind = "init"; - } else if (options.ecmaVersion >= 5 && prop.key.type === "Identifier" && - (prop.key.name === "get" || prop.key.name === "set")) { - isGetSet = sawGetSet = true; - kind = prop.kind = prop.key.name; - prop.key = parsePropertyName(); - if (tokType !== _parenL) unexpected(); - prop.value = parseFunction(startNode(), false); - } else unexpected(); - - // getters and setters are not allowed to clash — either with - // each other or with an init property — and in strict mode, - // init properties are also not allowed to be repeated. - - if (prop.key.type === "Identifier" && (strict || sawGetSet)) { - for (var i = 0; i < node.properties.length; ++i) { - var other = node.properties[i]; - if (other.key.name === prop.key.name) { - var conflict = kind == other.kind || isGetSet && other.kind === "init" || - kind === "init" && (other.kind === "get" || other.kind === "set"); - if (conflict && !strict && kind === "init" && other.kind === "init") conflict = false; - if (conflict) raise(prop.key.start, "Redefinition of property"); - } - } - } - node.properties.push(prop); - } - return finishNode(node, "ObjectExpression"); - } - - function parsePropertyName() { - if (tokType === _num || tokType === _string) return parseExprAtom(); - return parseIdent(true); - } - - // Parse a function declaration or literal (depending on the - // `isStatement` parameter). - - function parseFunction(node, isStatement) { - if (tokType === _name) node.id = parseIdent(); - else if (isStatement) unexpected(); - else node.id = null; - node.params = []; - var first = true; - expect(_parenL); - while (!eat(_parenR)) { - if (!first) expect(_comma); else first = false; - node.params.push(parseIdent()); - } - - // Start a new scope with regard to labels and the `inFunction` - // flag (restore them to their old value afterwards). - var oldInFunc = inFunction, oldLabels = labels; - inFunction = true; labels = []; - node.body = parseBlock(true); - inFunction = oldInFunc; labels = oldLabels; - - // If this is a strict mode function, verify that argument names - // are not repeated, and it does not try to bind the words `eval` - // or `arguments`. - if (strict || node.body.body.length && isUseStrict(node.body.body[0])) { - for (var i = node.id ? -1 : 0; i < node.params.length; ++i) { - var id = i < 0 ? node.id : node.params[i]; - if (isStrictReservedWord(id.name) || isStrictBadIdWord(id.name)) - raise(id.start, "Defining '" + id.name + "' in strict mode"); - if (i >= 0) for (var j = 0; j < i; ++j) if (id.name === node.params[j].name) - raise(id.start, "Argument name clash in strict mode"); - } - } - - return finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression"); - } - - // Parses a comma-separated list of expressions, and returns them as - // an array. `close` is the token type that ends the list, and - // `allowEmpty` can be turned on to allow subsequent commas with - // nothing in between them to be parsed as `null` (which is needed - // for array literals). - - function parseExprList(close, allowTrailingComma, allowEmpty) { - var elts = [], first = true; - while (!eat(close)) { - if (!first) { - expect(_comma); - if (allowTrailingComma && options.allowTrailingCommas && eat(close)) break; - } else first = false; - - if (allowEmpty && tokType === _comma) elts.push(null); - else elts.push(parseExpression(true)); - } - return elts; - } - - // Parse the next token as an identifier. If `liberal` is true (used - // when parsing properties), it will also convert keywords into - // identifiers. - - function parseIdent(liberal) { - var node = startNode(); - node.name = tokType === _name ? tokVal : (liberal && !options.forbidReserved && tokType.keyword) || unexpected(); - next(); - return finishNode(node, "Identifier"); - } - -}); - -(function (global) { - if (typeof window === "undefined") { - window = this; - } - //$data = window["$data"] || (window["$data"] = {}); - $data = window["$data"] || (window["$data"] = (function _data_handler() { - //console.log("@@@@", this); - if (this instanceof _data_handler) { - //console.log( - var type = _data_handler["implementation"].apply(this, arguments); - return new type(arguments[1]); - } else { - - return _data_handler["implementation"].apply(this, arguments) - } - })); -})(this); - -if (typeof console === 'undefined') { - console = { - warn: function () { }, - error: function () { }, - log: function () { }, - dir: function () { }, - time: function () { }, - timeEnd: function () { } - }; -} - -if (!console.warn) console.warn = function () { }; -if (!console.error) console.error = function () { }; - -(function ($data) { - /// - /// Collection of JayData services - /// - $data.__namespace = true; - $data.version = "JayData 1.3.6"; - $data.versionNumber = "1.3.6"; - $data.root = {}; - $data.Acorn = $data.Acorn || (typeof acorn == 'object' ? acorn : undefined); - $data.Esprima = $data.Esprima || (typeof esprima == 'object' ? esprima : undefined); - -})($data); - -// Do not remove this block, it is used by jsdoc -/** - @name $data.Base - @class base class -*/ -Exception = function(message, name, data) { - Error.call(this); - if (Error.captureStackTrace) - Error.captureStackTrace(this, this.constructor); - - this.name = name || "Exception"; - this.message = message; - this.data = data; - - //this.toString = function() { return JSON.stringify(this); }; - -} - -Exception.prototype.__proto__ = Error.prototype; - -Exception.prototype._getStackTrace = function () { - var callstack = []; - var isCallstackPopulated = false; - // unreachable code - //return; - /*try { - i.dont.exist += 0; - } - catch (e) { - if (e.stack) { // Firefox, Chrome - var lines = e.stack.split('\n'); - for (var i = 0, len = lines.length; i < len; i++) { - //if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) { - if (lines[i].indexOf(" at ") >= 0) - callstack.push(lines[i]); - } - //Remove call to printStackTrace() - callstack.shift(); - //TODO: Remove call to new Exception( chain - //callstack.shift(); - isCallstackPopulated = true; - } - else if (window.opera && e.message) { //Opera - var lines = e.message.split('\n'); - for (var i = 0, len = lines.length; i < len; i++) { - if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) { - var entry = lines[i]; - //Append next line also since it has the file info - if (lines[i + 1]) { - entry += ' at ' + lines[i + 1]; - i++; - } - callstack.push(entry); - } - } - //Remove call to printStackTrace() - callstack.shift(); - //TODO: Remove call to new Exception( chain - //callstack.shift(); - isCallstackPopulated = true; - } - } - - //if (!isCallstackPopulated) { //IE and Safari - // var currentFunction = arguments.callee.caller; - // while (currentFunction) { - // var fn = currentFunction.toString(); - // var fname = fn.substring(fn.indexOf("function") + 8, fn.indexOf('(')) || 'anonymous'; - // callstack.push(fname); - // if (currentFunction == currentFunction.caller) { - // Guard.raise("Infinite loop"); - // } - // currentFunction = currentFunction.caller; - // } - //} - return callstack.join("\n\r"); */ -}; -Guard = {}; -Guard.requireValue = function (name, value) { - if (typeof value === 'undefined' || value === null) { - Guard.raise(name + " requires a value other than undefined or null"); - } -}; - -Guard.requireType = function (name, value, typeOrTypes) { - var types = typeOrTypes instanceof Array ? typeOrTypes : [typeOrTypes]; - return types.some(function (item) { - switch (typeof item) { - case "string": - return typeof value === item; - case "function": - return value instanceof item; - default: - Guard.raise("Unknown type format : " + typeof item + " for: "+ name); - } - }); -}; - -Guard.raise = function(exception){ - if (typeof intellisense === 'undefined') { - if (exception instanceof Exception){ - console.error(exception.name + ':', exception.message + '\n', exception); - }else{ - console.error(exception); - } - throw exception; - } -}; - -Object.isNullOrUndefined = function (value) { - return value === undefined || value === null; -}; -(function ObjectMethodsForPreHTML5Browsers() { - - if (!Object.getOwnPropertyNames){ - Object.getOwnPropertyNames = function(o){ - var names = []; - - for (var i in o){ - if (o.hasOwnProperty(i)) names.push(i); - } - - return names; - }; - } - - if (!Object.create) { - Object.create = function (o) { - if (arguments.length > 1) { - Guard.raise(new Error('Object.create implementation only accepts the first parameter.')); - } - function F() { } - F.prototype = o; - return new F(); - }; - } - - if (!Object.keys) { - var hasOwnProperty = Object.prototype.hasOwnProperty, - hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'), - dontEnums = ['toString', - 'toLocaleString', - 'valueOf', - 'hasOwnProperty', - 'isPrototypeOf', - 'propertyIsEnumerable', - 'constructor'], - dontEnumsLength = dontEnums.length; - - Object.keys = function (obj) { - - ///Refactor to Assert.IsObjectOrFunction - if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) Guard.raise(new TypeError('Object.keys called on non-object')); - - var result = []; - - for (var prop in obj) { - if (hasOwnProperty.call(obj, prop)) { - result.push(prop); - } - } - - if (hasDontEnumBug) { - for (var i = 0; i < dontEnumsLength; i++) { - if (hasOwnProperty.call(obj, dontEnums[i])) { - result.push(dontEnums[i]); - } - } - } - - return result; - }; - } - - if (!Object.defineProperty) { - Object.defineProperty = function (obj, propName, propDef) { - obj[propName] = propDef.value || {}; - }; - } - - if (!Object.defineProperties) { - Object.defineProperties = function (obj, defines) { - for (var i in defines) { - if(defines.hasOwnProperty(i)) - obj[i] = defines[i].value || {}; - } - }; - } - - if (!Array.prototype.forEach) { - Array.prototype.forEach = function (handler, thisArg) { - for (var i = 0, l = this.length; i < l; i++) { - if (thisArg) { handler.call(thisArg, this[i], i, this); } - else { handler(this[i], i, this); }; - }; - }; - }; - - if (!Array.prototype.filter) { - Array.prototype.filter = function (handler, thisArg) { - var result = []; - for (var i = 0, l = this.length; i < l; i++) { - var r = thisArg ? - handler.call(thisArg, this[i], i, this) : - handler(this[i], i, this); - if (r === true) { - result.push(this[i]); - } - } - return result; - }; - } - - if (!Array.prototype.map) { - Array.prototype.map = function (handler, thisArg) { - var result = []; - for (var i = 0, l = this.length; i < l; i++) { - var r = thisArg ? - handler.call(thisArg, this[i], i, this) : - handler(this[i], i, this); - result.push(r); - } - return result; - }; - } - - if (!Array.prototype.some) { - Array.prototype.some = function (handler, thisArg) { - for (var i = 0, l = this.length; i < l; i++) { - var r = thisArg ? - handler.call(thisArg, this[i], i, this) : - handler(this[i], i, this); - if (r) { return true; } - - } - return false; - }; - } - - if (!Array.prototype.indexOf) { - Array.prototype.indexOf = function (item, from) { - for (var i = 0, l = this.length; i < l; i++) { - if (this[i] === item) { - return i; - }; - }; - return -1; - }; - } - - if (!String.prototype.trimLeft) { - String.prototype.trimLeft = function () { - return this.replace(/^\s+/, ""); - } - } - - if (!String.prototype.trimRight) { - String.prototype.trimRight = function () { - return this.replace(/\s+$/, ""); - } - } - - if (!Function.prototype.bind) { - Function.prototype.bind = function (oThis) { - if (typeof this !== "function") { - // closest thing possible to the ECMAScript 5 internal IsCallable function - throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); - } - - var aArgs = Array.prototype.slice.call(arguments, 1), - fToBind = this, - fNOP = function () { }, - fBound = function () { - return fToBind.apply(this instanceof fNOP && oThis - ? this - : oThis, - aArgs.concat(Array.prototype.slice.call(arguments))); - }; - - fNOP.prototype = this.prototype; - fBound.prototype = new fNOP(); - - return fBound; - }; - } - - if (typeof Uint8Array == 'undefined'){ - Uint8Array = function(v){ - if (v instanceof Uint8Array) return v; - var self = this; - var buffer = Array.isArray(v) ? v : new Array(v); - this.length = buffer.length; - this.byteLength = this.length; - this.byteOffset = 0; - this.buffer = { byteLength: self.length }; - var getter = function(index){ - return buffer[index]; - }; - var setter = function(index, value){ - buffer[index] = (value | 0) & 0xff; - }; - var makeAccessor = function(i){ - buffer[i] = buffer[i] || 0; - Object.defineProperty(self, i, { - enumerable: true, - configurable: false, - get: function(){ - if (isNaN(+i) || ((i | 0) < 0 || (i | 0) >= self.length)){ - try{ - if (typeof document != 'undefined') document.createTextNode("").splitText(1); - return new RangeError("INDEX_SIZE_ERR"); - }catch(e){ - return e; - } - } - return getter(i); - }, - set: function(v){ - if (isNaN(+i) || ((i | 0) < 0 || (i | 0) >= self.length)){ - try{ - if (typeof document != 'undefined') document.createTextNode("").splitText(1); - return new RangeError("INDEX_SIZE_ERR"); - }catch(e){ - return e; - } - } - setter(i | 0, v); - } - }); - }; - for (var i = 0; i < self.length; i++){ - makeAccessor(i); - } - }; - } - -})(); -(function init($data, global) { - - function il(msg) { - if (typeof intellisense !== 'undefined') { - if (!intellisense.i) { - intellisense.i = 0; - } - intellisense.i = intellisense.i + 1; - intellisense.logMessage(msg + ":" + intellisense.i); - } - } - - function MemberDefinition(memberDefinitionData, definedClass) { - - ///* - ///* - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - ///[false] if false value is stored in initData, otherwise on the object - ///[true] if set to false propertyChange events are not raise and property tracking is disabled - - this.kind = MemberTypes.property; - //this.definedBy = definedClass; - Object.defineProperty(this, 'definedBy', { value: definedClass, enumerable: false, configurable: false, writable: false }); - if (memberDefinitionData) { - if (typeof memberDefinitionData === 'function' || typeof memberDefinitionData.asFunction === 'function') { - this.method = memberDefinitionData; - this.kind = MemberTypes.method; - } else { - this.enumerable = true; - this.configurable = true; - if (typeof memberDefinitionData === "number") { - this.value = memberDefinitionData; - this.type = $data.Number; - this.dataType = $data.Number; - } else if (typeof memberDefinitionData === "string") { - this.value = memberDefinitionData; - this.dataType = $data.String; - this.type = $data.String; - } else { - for (var item in memberDefinitionData) { - if (memberDefinitionData.hasOwnProperty(item)) { - this[item] = memberDefinitionData[item]; - } - } - } - } - if (this.type !== undefined) { - this.dataType = this.dataType || this.type; - } else { - this.type = this.dataType; - } - - this.originalType = this.type; - if (this.elementType !== undefined) { - this.originalElementType = this.elementType; - } - } - } - MemberDefinition.prototype.createPropertyDescriptor = function (classFunction, value) { - /// - var pd = this; - var result = { - enumerable: this.enumerable == undefined ? true : this.enumerable, - configurable: this.configurable == undefined ? true : this.configurable - }; - if (this.set && this.get) { - result.set = this.set; - result.get = this.get; - } else if ("value" in this || value) { - result.value = value || this.value; - //TODO - //result.writable = this.writable; - result.writable = true; - } - else { - result.set = function (value) { this.storeProperty(pd, value); }; - result.get = function () { return this.retrieveProperty(pd); }; - } - return result; - }; - MemberDefinition.prototype.createStorePropertyDescriptor = function (value) { - var pd = this; - return { enumerable: false, writable: true, configurable: pd.configurable, value: value }; - }; - MemberDefinition.prototype.createGetMethod = function () { - var pd = this; - return { - enumerable: false, writable: false, configurable: false, - value: function (callback, tran) { return this.getProperty(pd, callback, tran); } - }; - }; - MemberDefinition.prototype.createSetMethod = function () { - var pd = this; - return { - enumerable: false, writable: false, configurable: false, - value: function (value, callback, tran) { return this.setProperty(pd, value, callback, tran); } - }; - }; - MemberDefinition.translateDefinition = function (memDef, name, classFunction) { - var holder = classFunction; - var memberDefinition; - - if (memDef.type && Container.isTypeRegistered(memDef.type)) { - holder = Container.resolveType(memDef.type); - if (typeof holder.translateDefinition === 'function') { - memberDefinition = holder.translateDefinition.apply(holder, arguments); - memberDefinition.name = memberDefinition.name || name; - } else { - holder = classFunction; - } - } - - - if (!(memberDefinition instanceof MemberDefinition)) { - memberDefinition = new MemberDefinition(memberDefinition || memDef, holder); - memberDefinition.name = name; - } - classFunction.resolverThunks = classFunction.resolverThunks || []; - classFunction.childResolverThunks = classFunction.childResolverThunks || []; - - - var t = memberDefinition.type; - var et = memberDefinition.elementType; - - function addChildThunk(referencedType) { - if (referencedType && referencedType.isAssignableTo && $data.Entity && referencedType.isAssignableTo($data.Entity)) { - classFunction.childResolverThunks.push(function () { - if (referencedType.resolveForwardDeclarations) { - referencedType.resolveForwardDeclarations(); - } - }); - } - } - - addChildThunk(t); - addChildThunk(et); - - if ("string" === typeof t) { - if ("@" === t[0]) { - memberDefinition.type = t.substr(1); - memberDefinition.dataType = t.substr(1); - } else { - //forward declared types get this callback when type is registered - classFunction.resolverThunks.push(function () { - var rt = classFunction.container.resolveType(t); - addChildThunk(rt); - memberDefinition.type = rt; - memberDefinition.dataType = rt; - }); - } - } - - if (et) { - if ("string" === typeof et) { - if ("@" === et[0]) { - memberDefinition.elementType = et.substr(1); - } else { - //forward declared types get this callback when type is registered - classFunction.resolverThunks.push(function () { - var rt = classFunction.container.resolveType(et); - addChildThunk(rt); - memberDefinition.elementType = rt; - }); - - } - } - } - - - //if (!classFunction) - - classFunction.resolveForwardDeclarations = function () { - classFunction.resolveForwardDeclarations = function () { }; - $data.Trace.log("resolving: " + classFunction.fullName); - this.resolverThunks.forEach(function (thunk) { - thunk(); - }); - //this.resolverThunks = []; - this.childResolverThunks.forEach(function (thunk) { - thunk(); - }); - //this.childResolverThunks = []; - } - - return memberDefinition; - }; - - MemberDefinition.prototype.toJSON = function () { - var property = {}; - for (var name in this) { - if (name !== 'defineBy' && name !== 'storageModel') { - if ((name === 'type' || name === 'dataType') && (this[name] && typeof this[name] === 'function')) { - try { - property[name] = Container.resolveName(this[name]); - } catch (e) { - property[name] = this[name]; - } - } else { - property[name] = this[name]; - } - } - } - return property; - } - - //TODO global/window - $data.MemberDefinition = window["MemberDefinition"] = MemberDefinition; - - var memberDefinitionPrefix = '$'; - function MemberDefinitionCollection() { }; - MemberDefinitionCollection.prototype = { - clearCache: function () { - this.arrayCache = undefined; - this.pubMapPropsCache = undefined; - this.keyPropsCache = undefined; - this.propByTypeCache = undefined; - this.pubMapMethodsCache = undefined; - this.pubMapPropNamesCache = undefined; - }, - asArray: function () { - if (!this.arrayCache) { - this.arrayCache = []; - for (var i in this) { - if (i.indexOf(memberDefinitionPrefix) === 0) - this.arrayCache.push(this[i]); - } - } - return this.arrayCache; - }, - getPublicMappedProperties: function () { - if (!this.pubMapPropsCache) { - this.pubMapPropsCache = []; - for (var i in this) { - if (i.indexOf(memberDefinitionPrefix) === 0 && this[i].kind == 'property' && !this[i].notMapped && this[i].enumerable) - this.pubMapPropsCache.push(this[i]); - } - } - return this.pubMapPropsCache;// || (this.pubMapPropsCache = this.asArray().filter(function (m) { return m.kind == 'property' && !m.notMapped && m.enumerable; })); - }, - getPublicMappedPropertyNames: function () { - if (!this.pubMapPropNamesCache) { - this.pubMapPropNamesCache = []; - for (var i in this) { - if (i.indexOf(memberDefinitionPrefix) === 0 && this[i].kind == 'property' && !this[i].notMapped && this[i].enumerable) - this.pubMapPropNamesCache.push(this[i].name); - } - } - return this.pubMapPropNamesCache; - }, - getKeyProperties: function () { - if (!this.keyPropsCache) { - this.keyPropsCache = []; - for (var i in this) { - if (i.indexOf(memberDefinitionPrefix) === 0 && this[i].kind == 'property' && this[i].key) - this.keyPropsCache.push(this[i]); - } - } - return this.keyPropsCache; - //return this.keyPropsCache || (this.keyPropsCache = this.asArray().filter(function (m) { return m.kind == 'property' && m.key; })); - }, - getPublicMappedMethods: function () { - if (!this.pubMapMethodsCache) { - this.pubMapMethodsCache = []; - for (var i in this) { - if (i.indexOf(memberDefinitionPrefix) === 0 && this[i].kind == 'method' && this[i].method/* && this.hasOwnProperty(i)*/) - this.pubMapMethodsCache.push(this[i]); - } - } - return this.pubMapMethodsCache; - }, - getPropertyByType: function (type) { - if (!this.propByTypeCache) { - this.propByTypeCache = []; - for (var i in this) { - if (i.indexOf(memberDefinitionPrefix) === 0 && this[i].dataType == type) - this.propByTypeCache.push(this[i]); - } - } - return this.propByTypeCache; - //return this.propByTypeCache || (this.propByTypeCache = this.asArray().filter(function (m) { return m.dataType == type; })); - }, - getMember: function (name) { return this[memberDefinitionPrefix + name]; }, - setMember: function (value) { this[memberDefinitionPrefix + value.name] = value; } - }; - MemberDefinitionCollection.prototype.constructor = MemberDefinitionCollection; - $data.MemberDefinitionCollection = window["MemberDefinitionCollection"] = MemberDefinitionCollection; - - function ClassEngineBase() { - this.classNames = {}; - } - - function MemberTypes() { - /// - /// - /// - /// - } - MemberTypes.__enum = true; - - MemberTypes.method = "method"; - MemberTypes.property = "property"; - MemberTypes.navProperty = "navProperty"; - MemberTypes.complexProperty = "complexProperty"; - MemberTypes.field = "field"; - - $data.MemberTypes = MemberTypes; - - //function classToJSON() { - // var ret = {}; - // for (var i in this) { - // if (this.hasOwnProperty(i)) { - // ret[i] = this[i]; - // } - // } - // return ret; - //} - //$data.Base.toJSON = classToJSON; - - ClassEngineBase.prototype = { - - //getClass: function (classReference) { - //}, - - //getProperties: function (classFunction) { - // return classFunction.propertyDefinitions; - //}, - - define: function (className, baseClass, container, instanceDefinition, classDefinition) { - /// - /// Creates a Jaydata type - /// Name of the class - /// Basetype of the class - /// - /// Class definition (properties, methods, etc) - /// Class static definition - /// - /// - /// var t = new $data.Class.define('Types.A', $data.Base, null, { - /// constructor: function(){ }, - /// func1: function(){ }, - /// member1: { type: 'string' } - /// }, { - /// staticFunc1: function() {} - /// }) - /// - /// - /// - - return this.defineEx(className, [{ type: baseClass }], container, instanceDefinition, classDefinition); - }, - defineEx: function (className, baseClasses, container, instanceDefinition, classDefinition) { - /// - /// Creates a Jaydata type - /// Name of the class - /// Basetypes of the class. First is a real base, others are mixins - /// - /// Class definition (properties, methods, etc) - /// Class static definition - /// - /// - /// var t = new $data.Class.define('Types.A', [$data.Base, $data.Mixin1, $data.Mixin2], null, { - /// constructor: function(){ }, - /// func1: function(){ }, - /// member1: { type: 'string' } - /// }, { - /// staticFunc1: function() {} - /// }) - /// - /// - /// - /// - /// Creates a Jaydata type - /// Name of the class - /// Basetypes of the class. First is a real base, others are mixins or propagations - /// - /// Class definition (properties, methods, etc) - /// Class static definition - /// - /// - /// var t = new $data.Class.define('Types.A', [ - /// { type: $data.Base, params: [1, 'secondParameterValue', new ConstructorParameter(0)] }, - /// { type: $data.Mixin1, }, - /// { type: $data.Mixin2, }, - /// { type: $data.Propagation1, params: [new ConstructorParameter(1)], propagateTo:'Propagation1' }, - /// { type: $data.Propagation2, params: ['firstParameterValue'], propagateTo:'Propagation2' } - /// ], null, { - /// constructor: function(){ }, - /// func1: function(){ }, - /// member1: { type: 'string' } - /// }, { - /// staticFunc1: function() {} - /// }) - /// - /// - /// - - container = container || $data.Container; - - if (baseClasses.length == 0) { - baseClasses.push({ type: $data.Base }); - } else if (baseClasses.length > 0 && !baseClasses[0].type) { - baseClasses[0].type = $data.Base; - } - for (var i = 0, l = baseClasses.length; i < l; i++) { - if (typeof baseClasses[i] === 'function') - baseClasses[i] = { type: baseClasses[i] }; - } - - var providedCtor = instanceDefinition ? instanceDefinition.constructor : undefined; - - var classNameParts = className.split('.'); - var shortClassName = classNameParts.splice(classNameParts.length - 1, 1)[0]; - - var root = container === $data.Container ? window : container; - for (var i = 0; i < classNameParts.length; i++) { - var part = classNameParts[i]; - if (!root[part]) { - var ns = {}; - ns.__namespace = true; - root[part] = ns; - } - root = root[part]; - } - - - var classFunction = null; - classFunction = this.classFunctionBuilder(shortClassName, baseClasses, classDefinition, instanceDefinition); - classFunction.fullName = className; - classFunction.namespace = classNameParts.join('.'); //classname splitted - classFunction.name = shortClassName; - classFunction.container = container; - classFunction.container.registerType(className, classFunction); - - this.buildType(classFunction, baseClasses, instanceDefinition, classDefinition); - - - - if (typeof intellisense !== 'undefined') { - if (instanceDefinition && instanceDefinition.constructor) { - intellisense.annotate(classFunction, instanceDefinition.constructor); - } - } - - root[shortClassName] = this.classNames[className] = classFunction; - //classFunction.toJSON = classToJSON; - var baseCount = classFunction.baseTypes.length; - for (var i = 0; i < baseCount; i++) { - var b = classFunction.baseTypes[i]; - if ("inheritedTypeProcessor" in b) { - b.inheritedTypeProcessor(classFunction); - } - } - //classFunction.prototype.constructor = instanceDefinition.constructor; - //classFunction.constructor = instanceDefinition.constructor; - //classFunction.toJSON = function () { return classFunction.memberDefinitions.filter( function(md) { return md; }; - return classFunction; - }, - classFunctionBuilder: function (name, base, classDefinition, instanceDefinition) { - var body = this.bodyBuilder(base, classDefinition, instanceDefinition); - return new Function('base', 'classDefinition', 'instanceDefinition', 'name', 'return function ' + name + ' (){ ' + - body + ' \n}; ')(base, classDefinition, instanceDefinition, name); - }, - bodyBuilder: function (bases, classDefinition, instanceDefinition) { - var mixin = ''; - var body = ''; - var propagation = ''; - - for (var i = 0, l = bases.length; i < l; i++) { - var base = bases[i]; - var index = i; - if (index == 0) { //ctor func - if (base && base.type && base.type !== $data.Base && base.type.fullName) { - body += ' var baseArguments = $data.typeSystem.createCtorParams(arguments, base[' + index + '].params, this); \n'; - body += ' ' + base.type.fullName + '.apply(this, baseArguments); \n'; - } - } else { - if (base && base.type && base.propagateTo) { - //propagation - propagation += ' ' + (!propagation ? 'var ' : '' + '') + 'propagationArguments = $data.typeSystem.createCtorParams(arguments, base[' + index + '].params, this); \n'; - propagation += ' this["' + base.propagateTo + '"] = Object.create(' + base.type.fullName + '.prototype); \n' + - ' ' + base.type.fullName + '.apply(this["' + base.propagateTo + '"], propagationArguments); \n'; - } - else if (base && base.type && base.type.memberDefinitions && base.type.memberDefinitions.$constructor && !base.propagateTo) { - //mixin - mixin += ' ' + base.type.fullName + '.memberDefinitions.$constructor.method.apply(this); \n'; - } - } - } - if (instanceDefinition && instanceDefinition.constructor != Object) - body += " instanceDefinition.constructor.apply(this, arguments); \n"; - - return '\n //mixins \n' + mixin + '\n //construction \n' + body + '\n //propagations \n' + propagation; - }, - - buildType: function (classFunction, baseClasses, instanceDefinition, classDefinition) { - var baseClass = baseClasses[0].type; - classFunction.inheritsFrom = baseClass; - - if (baseClass) { - classFunction.prototype = Object.create(baseClass.prototype); - classFunction.memberDefinitions = Object.create(baseClass.memberDefinitions || new MemberDefinitionCollection()); - classFunction.memberDefinitions.clearCache(); - - var staticDefs = baseClass.staticDefinitions; - if (staticDefs) { - staticDefs = staticDefs.asArray(); - if (staticDefs) { - for (var i = 0; i < staticDefs.length; i++) { - this.buildMember(classFunction, staticDefs[i], undefined, 'staticDefinitions'); - } - } - } - classFunction.baseTypes = baseClass.baseTypes ? [].concat(baseClass.baseTypes) : []; - for (var i = 0; i < baseClasses.length; i++) { - classFunction.baseTypes.push(baseClasses[i].type); - } - //classFunction.baseTypes = (baseClass.baseTypes || []).concat(baseClasses.map(function (base) { return base.type; })); - if (!classFunction.isAssignableTo) { - Object.defineProperty(classFunction, "isAssignableTo", { - value: function (type) { - return this === type || this.baseTypes.indexOf(type) >= 0; - }, - writable: false, - enumerable: false, - configurable: false - }); - } - } - - if (classDefinition) { - this.buildStaticMembers(classFunction, classDefinition); - - if (classDefinition.constructor) - classFunction.classConstructor = classDefinition.constructor; - } - - if (instanceDefinition) { - this.buildInstanceMembers(classFunction, instanceDefinition); - } - - var mixins = [].concat(baseClasses); - mixins.shift(); - if (Object.keys(mixins).length > 0) - this.buildInstanceMixins(classFunction, mixins); - - classFunction.__class = true; - - classFunction.prototype.constructor = classFunction; - - Object.defineProperty(classFunction.prototype, "getType", { - value: function () { - return classFunction; - }, - writable: false, - enumerable: false, - configurable: false - }); - }, - - addMethod: function (holder, name, method, propagation) { - if (!propagation || (typeof intellisense !== 'undefined')) { - holder[name] = method; - } else { - holder[name] = function () { - return method.apply(this[propagation], arguments); - }; - } - }, - - addProperty: function (holder, name, propertyDescriptor, propagation) { - - //holder[name] = {}; - - if (propagation) { - propertyDescriptor.configurable = true; - if (propertyDescriptor.get) { - var origGet = propertyDescriptor.get; - propertyDescriptor.get = function () { - if (!this[propagation]) - Guard.raise(new Exception("not inicialized")); - return origGet.apply(this[propagation], arguments); - }; - } - if (propertyDescriptor.set) { - var origSet = propertyDescriptor.set; - propertyDescriptor.set = function () { - if (!this[propagation]) - Guard.raise(new Exception("not inicialized")); - origSet.apply(this[propagation], arguments); - }; - } - } - - Object.defineProperty(holder, name, propertyDescriptor); - }, - - addField: function (holder, name, field) { - Guard.raise("not implemented"); - }, - - buildMethod: function (classFunction, memberDefinition, propagation) { - ///The object that will receive member - ///the newly added member - var holder = memberDefinition.classMember ? classFunction : classFunction.prototype; - this.addMethod(holder, memberDefinition.name, memberDefinition.method, propagation); - }, - - buildProperty: function (classFunction, memberDefinition, propagation) { - ///The object that will receive member - ///the newly added member - var holder = memberDefinition.classMember ? classFunction : classFunction.prototype; - var pd = memberDefinition.createPropertyDescriptor(classFunction); - this.addProperty(holder, memberDefinition.name, pd, propagation); - - //if lazyload TODO - if (!memberDefinition.classMember && classFunction.__setPropertyfunctions == true && memberDefinition.withoutGetSetMethod !== true && - !('get_' + memberDefinition.name in holder || 'set_' + memberDefinition.name in holder)) { - var pdGetMethod = memberDefinition.createGetMethod(); - this.addProperty(holder, 'get_' + memberDefinition.name, pdGetMethod, propagation); - - var pdSetMethod = memberDefinition.createSetMethod(); - this.addProperty(holder, 'set_' + memberDefinition.name, pdSetMethod, propagation); - } - }, - - - buildMember: function (classFunction, memberDefinition, propagation, memberCollectionName) { - /// - memberCollectionName = memberCollectionName || 'memberDefinitions'; - classFunction[memberCollectionName] = classFunction[memberCollectionName] || new MemberDefinitionCollection(); - classFunction[memberCollectionName].setMember(memberDefinition); - - switch (memberDefinition.kind) { - case MemberTypes.method: - this.buildMethod(classFunction, memberDefinition, propagation); - break; - case MemberTypes.navProperty: - case MemberTypes.complexProperty: - case MemberTypes.property: - this.buildProperty(classFunction, memberDefinition, propagation); - break; - default: Guard.raise("Unknown member type: " + memberDefinition.kind + "," + memberDefinition.name); - } - }, - - buildStaticMembers: function (classFunction, memberListDefinition) { - ///The class constructor that will be extended - /// - var t = this; - for (var item in memberListDefinition) { - if (memberListDefinition.hasOwnProperty(item)) { - var memberDefinition = MemberDefinition.translateDefinition(memberListDefinition[item], item, classFunction); - memberDefinition.classMember = true; - t.buildMember(classFunction, memberDefinition, undefined, 'staticDefinitions'); - } - } - }, - - buildInstanceMembers: function (classFunction, memberListDefinition) { - ///The class constructor whose prototype will be extended - /// - ///pinning t outside of the closure seems actually faster then passing in the this and referencing - var t = this; - for (var item in memberListDefinition) { - if (memberListDefinition.hasOwnProperty(item)) { - var memberDefinition = MemberDefinition.translateDefinition(memberListDefinition[item], item, classFunction); - t.buildMember(classFunction, memberDefinition, undefined, 'memberDefinitions'); - } - } - }, - - copyMembers: function (sourceType, targetType) { - /// - /// - function il(msg) { - if (typeof intellisense === 'undefined') { - return; - } - intellisense.logMessage(msg); - } - - Object.keys(sourceType.prototype).forEach(function (item, i, src) { - if (item !== 'constructor' && item !== 'toString') { - il("copying item:" + item); - targetType.prototype[item] = sourceType[item]; - } - }); - }, - - buildInstanceMixins: function (classFunction, mixinList) { - ///The class constructor whose prototype will be extended - /// - - classFunction.mixins = classFunction.mixins || []; - classFunction.propagations = classFunction.propagations || []; - - for (var i = 0; i < mixinList.length; i++) { - var item = mixinList[i]; - //if (classFunction.memberDefinitions.getMember(item.type.name)) { - if (item.propagateTo) { - this.buildInstancePropagation(classFunction, item); - classFunction.propagations.push(item); - classFunction.propagations[item.type.name] = true; - } else { - this.buildInstanceMixin(classFunction, item); - classFunction.mixins.push(item); - classFunction.mixins[item.type.name] = true; - } - }; - }, - buildInstanceMixin: function (classFunction, typeObj) { - ///The class constructor whose prototype will be extended - /// - - var memberDefs = typeObj.type.memberDefinitions.asArray(); - for (var i = 0, l = memberDefs.length; i < l; i++) { - var itemName = memberDefs[i].name; - if (itemName !== 'constructor' && !classFunction.memberDefinitions.getMember(itemName)) { - this.buildMember(classFunction, memberDefs[i]); - } - } - - if (typeObj.type.staticDefinitions) { - var staticDefs = typeObj.type.staticDefinitions.asArray(); - for (var i = 0, l = staticDefs.length; i < l; i++) { - var itemName = staticDefs[i].name; - if (itemName !== 'constructor' && !classFunction.memberDefinitions.getMember(itemName)) { - this.buildMember(classFunction, staticDefs[i], undefined, 'staticDefinitions'); - } - } - } - }, - buildInstancePropagation: function (classFunction, typeObj) { - ///The class constructor whose prototype will be extended - /// - - var memberDefs = typeObj.type.memberDefinitions.asArray(); - for (var i = 0, l = memberDefs.length; i < l; i++) { - var itemName = memberDefs[i].name; - if (itemName !== 'constructor' && !classFunction.memberDefinitions.getMember(itemName)) { - this.buildMember(classFunction, memberDefs[i], typeObj.propagateTo); - } - } - } - - }; - - $data.Class = Class = new ClassEngineBase(); - - //(function (global) { - global = window; - function ContainerCtor(parentContainer) { - var parent = parentContainer; - if (parent) { - parent.addChildContainer(this); - } - - var classNames = {}; - var consolidatedClassNames = []; - var classTypes = []; - - this.classNames = classNames; - this.consolidatedClassNames = consolidatedClassNames; - this.classTypes = classTypes; - - var mappedTo = []; - this.mappedTo = mappedTo; - - var self = this; - - this["holder"] = null; - - var IoC = function (type, parameters) { - var t = self.resolveType(type); - var inst = Object.create(t.prototype); - t.apply(inst, parameters); - return inst; - }; - - var pendingResolutions = {}; - this.pendingResolutions = pendingResolutions; - - function addPendingResolution(name, onResolved) { - pendingResolutions[name] = pendingResolutions[name] || []; - pendingResolutions[name].push(onResolved); - } - - this.addChildContainer = function (container) { - //children.push(container); - } - - this.createInstance = function (type, parameters) { return IoC(type, parameters); }; - - this.mapType = function (aliasTypeOrName, realTypeOrName) { - Guard.requireValue("aliasType", aliasTypeOrName); - Guard.requireValue("realType", realTypeOrName); - var aliasT = this.getType(aliasTypeOrName); - var realT = this.getType(realTypeOrName); - var aliasPos = classTypes.indexOf(aliasT); - var realPos = classTypes.indexOf(realT); - mappedTo[aliasPos] = realPos; - }, - - //this.resolve = function (type, parameters) { - // var classFunction = this.resolveType(type, parameters); - // return new classFunction(parameters); - //}; - - - - this.isPrimitiveType = function (type) { - var t = this.resolveType(type); - - switch (true) { - case t === Number: - case t === String: - case t === Date: - case t === Boolean: - case t === Array: - case t === Object: - - case t === $data.Number: - case t === $data.Integer: - case t === $data.Date: - case t === $data.String: - case t === $data.Boolean: - case t === $data.Array: - case t === $data.Object: - case t === $data.Guid: - - case t === $data.Byte: - case t === $data.SByte: - case t === $data.Decimal: - case t === $data.Float: - case t === $data.Int16: - case t === $data.Int32: - case t === $data.Int64: - case t === $data.DateTimeOffset: - case t === $data.Time: - - case t === $data.SimpleBase: - case t === $data.Geospatial: - case t === $data.GeographyBase: - case t === $data.GeographyPoint: - case t === $data.GeographyLineString: - case t === $data.GeographyPolygon: - case t === $data.GeographyMultiPoint: - case t === $data.GeographyMultiLineString: - case t === $data.GeographyMultiPolygon: - case t === $data.GeographyCollection: - case t === $data.GeometryBase: - case t === $data.GeometryPoint: - case t === $data.GeometryLineString: - case t === $data.GeometryPolygon: - case t === $data.GeometryMultiPoint: - case t === $data.GeometryMultiLineString: - case t === $data.GeometryMultiPolygon: - case t === $data.GeometryCollection: - - return true; - default: - return false; - } - - //return t === Number || t === String || t === Date || t === String || t === Boolean || t === Array || t === Object || - // t === $data.Number || t === $data.Integer || t === $data.Date || t === $data.String || t === $data.Boolean || t === $data.Array || t === $data.Object || - // t === $data.GeographyPoint || t === $data.Guid; - }; - - - this.resolveName = function (type) { - var t = this.resolveType(type); - var tPos = classTypes.indexOf(t); - return consolidatedClassNames[tPos]; - }; - - this.resolveType = function (typeOrName, onResolved) { - //if ("string" === typeof typeOrName) { - // console.log("@@@@String type!!!", typeOrName) - //} - var t = typeOrName; - t = this.getType(t, onResolved ? true : false, onResolved); - var posT = classTypes.indexOf(t); - return typeof mappedTo[posT] === 'undefined' ? t : classTypes[mappedTo[posT]]; - }; - - - - this.getType = function (typeOrName, doNotThrow, onResolved) { - Guard.requireValue("typeOrName", typeOrName); - if (typeof typeOrName === 'function') { - return typeOrName; - }; - - if (!(typeOrName in classNames)) { - if (parent) { - var tp = parent.getType(typeOrName, true); - if (tp) return tp; - } - if (onResolved) { - addPendingResolution(typeOrName, onResolved); - return; - } - else if (doNotThrow) { - return undefined; - } else { - Guard.raise(new Exception("Unable to resolve type:" + typeOrName)); - } - }; - var result = classTypes[classNames[typeOrName]]; - if (onResolved) { - onResolved(result); - } - return result; - }; - - this.getName = function (typeOrName) { - var t = this.getType(typeOrName); - var tPos = classTypes.indexOf(t); - if (tPos == -1) - Guard.raise("unknown type to request name for: " + typeOrName); - return consolidatedClassNames[tPos]; - }; - - this.getTypes = function () { - var keys = Object.keys(classNames); - var ret = []; - for (var i = 0; i < keys.length; i++) { - var className = keys[i]; - ret.push({ name: className, type: classTypes[classNames[className]], toString: function () { return this.name; } }); - } - return ret; - }; - - //this.getTypeName( in type); - //this.resolveType() - //this.inferTypeFromValue = function (value) { - - this.getTypeName = function (value) { - //TODO refactor - switch (typeof value) { - case 'object': - if (value == null) return '$data.Object'; - if (value instanceof Array) return '$data.Array'; - if (value.getType) return value.getType().fullName; - if (value instanceof Date) return '$data.Date'; - if (value instanceof $data.Guid) return '$data.Guid'; - if (value instanceof $data.DateTimeOffset) return '$data.DateTimeOffset'; - if (value instanceof $data.GeographyPoint) return '$data.GeographyPoint'; - if (value instanceof $data.GeographyLineString) return '$data.GeographyLineString'; - if (value instanceof $data.GeographyPolygon) return '$data.GeographyPolygon'; - if (value instanceof $data.GeographyMultiPoint) return '$data.GeographyMultiPoint'; - if (value instanceof $data.GeographyMultiLineString) return '$data.GeographyMultiLineString'; - if (value instanceof $data.GeographyMultiPolygon) return '$data.GeographyMultiPolygon'; - if (value instanceof $data.GeographyCollection) return '$data.GeographyCollection'; - if (value instanceof $data.GeographyBase) return '$data.GeographyBase'; - if (value instanceof $data.GeometryPoint) return '$data.GeometryPoint'; - if (value instanceof $data.GeometryLineString) return '$data.GeometryLineString'; - if (value instanceof $data.GeometryPolygon) return '$data.GeometryPolygon'; - if (value instanceof $data.GeometryMultiPoint) return '$data.GeometryMultiPoint'; - if (value instanceof $data.GeometryMultiLineString) return '$data.GeometryMultiLineString'; - if (value instanceof $data.GeometryMultiPolygon) return '$data.GeometryMultiPolygon'; - if (value instanceof $data.GeometryCollection) return '$data.GeometryCollection'; - if (value instanceof $data.GeometryBase) return '$data.GeometryBase'; - if (value instanceof $data.Geospatial) return '$data.Geospatial'; - if (value instanceof $data.SimpleBase) return '$data.SimpleBase'; - if (typeof value.toHexString === 'function') return '$data.ObjectID'; - //if(value instanceof "number") return - default: - return typeof value; - } - }; - - this.isTypeRegistered = function (typeOrName) { - if (typeof typeOrName === 'function') { - return classTypes.indexOf(typeOrName) > -1; - } else { - return typeOrName in classNames; - } - }; - - this.unregisterType = function (type) { - Guard.raise("Unimplemented"); - }; - - - - this.getDefault = function (typeOrName) { - var t = this.resolveType(typeOrName); - switch (t) { - case $data.Number: return 0.0; - case $data.Float: return 0.0; - case $data.Decimal: return '0.0'; - case $data.Integer: return 0; - case $data.Int16: return 0; - case $data.Int32: return 0; - case $data.Int64: return '0'; - case $data.Byte: return 0; - case $data.SByte: return 0; - case $data.String: return null; - case $data.Boolean: return false; - default: return null; - } - }; - - //name array ['', '', ''] - this.getIndex = function (typeOrName) { - var t = this.resolveType(typeOrName); - return classTypes.indexOf(t); - } - - this.resolveByIndex = function (index) { - return classTypes[index]; - } - - this.registerType = function (nameOrNamesArray, type, factoryFunc) { - /// - ///Registers a type and optionally a lifetimeManager with a name - ///that can be used to later resolve the type or create new instances - ///The names of the type - ///The type to register - /// - /// - /// - ///Registers a new type that - ///The name of the type - ///The type to register - /// - - - ///TODO remove - /*if (typeof typeNameOrAlias === 'string') { - if (classNames.indexOf(typeNameOrAlias) > -1) { - Guard.raise("Type already registered. Remove first"); - } - }*/ - - if (!nameOrNamesArray) { - return; - } - - //todo add ('number', 'number') - if (typeof type === "string") { - type = self.resolveType(type); - } - - var namesArray = []; - if (typeof nameOrNamesArray === 'string') { - var tmp = []; - tmp.push(nameOrNamesArray); - namesArray = tmp; - } else { - namesArray = nameOrNamesArray; - } - - for (var i = 0; i < namesArray.length; i++) { - var parts = namesArray[i].split('.'); - var item = {}; - item.shortName = parts[parts.length - 1]; - item.fullName = namesArray[i]; - namesArray[i] = item; - } - - //if (type. - - - var creatorFnc = function () { return IoC(type, arguments); }; - - if (typeof intellisense !== 'undefined') { - intellisense.annotate(creatorFnc, type); - } - - for (var i = 0, l = namesArray.length; i < l; i++) { - var item = namesArray[i]; - if (!(("create" + item.shortName) in self)) { - if (typeof factoryFunc === 'function') { - self["create" + item.shortName] = factoryFunc; - } else { - self["create" + item.shortName] = creatorFnc; - } - } - - var typePos = classTypes.indexOf(type); - if (typePos == -1) { - //new type - typePos = classTypes.push(type) - 1; - var fn = item.fullName; - consolidatedClassNames[typePos] = item.fullName; - }; - - classNames[item.fullName] = typePos; - - var pending = pendingResolutions[item.fullName] || []; - if (pending.length > 0) { - pending.forEach(function (t) { - t(type); - }); - pendingResolutions[item.fullName] = []; - } - } - if (parent) { - parent.registerType.apply(parent, arguments); - } - if (!type.name) { - type.name = namesArray[0].shortName; - } - }; - - - var _converters = { - from: {}, - to: {} - }; - this.converters = _converters; - - this.convertTo = function (value, tType, eType /*if Array*/, options) { - Guard.requireValue("typeOrName", tType); - - if(Object.isNullOrUndefined(value)) - return value; - - var sourceTypeName = Container.getTypeName(value); - var sourceType = Container.resolveType(sourceTypeName); - var sourceTypeName = Container.resolveName(sourceType); - var targetType = Container.resolveType(tType); - var targetTypeName = Container.resolveName(targetType); - - var result; - try { - if (typeof targetType['from' + sourceTypeName] === 'function') { - // target from - result = targetType['from' + sourceTypeName].apply(targetType, arguments); - - } else if (typeof sourceType['to' + targetTypeName] === 'function') { - // source to - result = sourceType['to' + targetTypeName].apply(sourceType, arguments); - - } else if (_converters.to[targetTypeName] && _converters.to[targetTypeName][sourceTypeName]) { - // target from source - result = _converters.to[targetTypeName][sourceTypeName].apply(_converters, arguments); - - } else if (_converters.from[sourceTypeName] && _converters.from[sourceTypeName][targetTypeName]) { - // source to target - result = _converters.from[sourceTypeName][targetTypeName].apply(_converters, arguments); - - } else if (targetTypeName === sourceTypeName || value instanceof targetType) { - result = value; - - } else if (_converters.to[targetTypeName] && _converters.to[targetTypeName]['default']) { - // target from anything - result = _converters.to[targetTypeName]['default'].apply(_converters, arguments); - - } else { - throw "converter not found"; - } - } catch (e) { - Guard.raise(new Exception("Value '" + sourceTypeName + "' not convertable to '" + targetTypeName + "'", 'TypeError', value)); - } - - if (targetType === $data.Array && eType && Array.isArray(result)) { - for (var i = 0; i < result.length; i++) { - result[i] = this.convertTo.call(this, result[i], eType, undefined, options); - } - } - - return result; - }; - this.registerConverter = function (target, sourceOrToConverters, toConverterOrFromConverters, fromConverter) { - //registerConverter($data.Guid, { $data.String: fn, int: fn }, { string: fn, int:fn }) - //registerConverter($data.Guid, $data.String, fn, fn); - - var targetName = Container.resolveName(target); - if (Container.isTypeRegistered(sourceOrToConverters)) { - //isSource - _converters.to[targetName] = _converters.to[targetName] || {}; - _converters.from[targetName] = _converters.from[targetName] || {}; - - var sourceName = Container.resolveName(sourceOrToConverters); - - if (toConverterOrFromConverters) - _converters.to[targetName][sourceName] = toConverterOrFromConverters; - if (fromConverter) - _converters.from[targetName][sourceName] = fromConverter; - - } else { - // converterGroup - - //fromConverters - if (_converters.to[targetName]) { - _converters.to[targetName] = $data.typeSystem.extend(_converters.to[targetName], sourceOrToConverters); - } else { - _converters.to[targetName] = sourceOrToConverters; - } - - //toConverters - if (_converters.from[targetName]) { - _converters.from[targetName] = $data.typeSystem.extend(_converters.from[targetName], toConverterOrFromConverters); - } else { - _converters.from[targetName] = toConverterOrFromConverters; - } - } - }; - } - $data.ContainerClass = ContainerCtor; - - var c; - - global["Container"] = $data.Container = c = global["C$"] = new ContainerCtor(); - - $data.createContainer = function () { - return new ContainerCtor($data.Container); - } - - //})(window); - - global["$C"] = function () { Class.define.apply(Class, arguments); }; - - - var storeProperty = function (memberDefinition, value) { - var backingFieldName = "_" + memberDefinition.name; - if (!this[backingFieldName]) { - Object.defineProperty(this, backingFieldName, memberDefinition.createStorePropertyDescriptor(value)); - } - else { - this[backingFieldName] = value; - } - }; - var retrieveProperty = function (memberDefinition) { - var backingFieldName = "_" + memberDefinition.name; - return this[backingFieldName]; - }; - - - $data.Class.define('$data.Base', function Base() { }, null, { - storeProperty: storeProperty, - retrieveProperty: retrieveProperty, - setProperty: function (memberDefinition, value, callback) { - this[memberDefinition.name] = value; - callback(); - }, - getProperty: function (memberDefinition, callback) { - callback.apply(this, [this[memberDefinition.name]]); - } - }, { - create: function () { return Container.createInstance(this, arguments); }, - extend: function (name, container, instanceDefinition, classDefinition) { - if (container && !(container instanceof ContainerCtor)) { - classDefinition = instanceDefinition; - instanceDefinition = container; - container = undefined; - } - return $data.Class.define(name, this, container, instanceDefinition, classDefinition); - }, - getMemberDefinition: function (name) { - return this.memberDefinitions.getMember(name); - }, - addProperty: function (name, getterOrType, setterOrGetter, setter) { - var _getter = getterOrType; - var _setter = setterOrGetter; - var _type; - if (typeof _getter === 'string') { - _type = getterOrType; - _getter = setterOrGetter; - _setter = setter; - } - - var propDef = { - notMapped: true, - storeOnObject: true, - get: typeof _getter === 'function' ? _getter : function () { }, - set: typeof _setter === 'function' ? _setter : function () { }, - type: _type - }; - - var memberDefinition = MemberDefinition.translateDefinition(propDef, name, this); - $data.Class.buildMember(this, memberDefinition); - - this.memberDefinitions.clearCache(); - - return this; - }, - addMember: function (name, definition, isClassMember) { - var memberDefinition = MemberDefinition.translateDefinition(definition, name, this); - - if (isClassMember) { - memberDefinition.classMember = true; - $data.Class.buildMember(this, memberDefinition, undefined, 'staticDefinitions'); - this.staticDefinitions.clearCache(); - } else { - $data.Class.buildMember(this, memberDefinition); - this.memberDefinitions.clearCache(); - } - return this; - }, - describeField: function (name, definition) { - var memDef = this.memberDefinitions.getMember(name); - if (!memDef) { - this.addMember(name, definition); - } else { - Guard.raise(new Exception("Field '" + name + "' already defined!", "Invalid operation")); - } - return this; - }, - storeProperty: storeProperty, - retrieveProperty: retrieveProperty, - 'from$data.Object': function (value) { - return value; - } - }); - - - //override after typeSystem initialized - - - $data.Class.ConstructorParameter = ConstructorParameter = $data.Class.define('ConstructorParameter', null, null, { - constructor: function (paramIndex) { - /// - this.paramIndex = paramIndex; - }, - paramIndex: {} - }); - /*$data.Class.MixinParameter = MixinParameter = $data.Class.define('MixinParameter', null, null, { - constructor: function (typeName) { - /// - this.typeName = typeName; - }, - typeName: {} - });*/ - - //var e = new Entity(); - - - /*$data.Interface = Class.define("Interface", null, null, { - constructor: function() { Guard.raise("Can not create an interface"); } - }, - { - define: function (name, definition) { - var result = Class.define(name, $data.Interface, null, null, definition); - delete result.__class; - result.__interface = true; - return result; - } - }); - - - - $data.Observable = Observable = Class.define("Observable", null, null, { - propertyChanged: { dataType: $data.Event } - }, { - createFromInstance: function(instance) { - var propNames = instance.getClass().memberDefinitions.f - } - });*/ - - - -})($data, window); - -$data.defaultErrorCallback = function () { - //console.log('DEFAULT ERROR CALLBACK:'); - /*if (console.dir) - console.dir(arguments); - else - console.log(arguments);*/ - if (arguments.length > 0 && arguments[arguments.length - 1] && typeof arguments[arguments.length - 1].reject === 'function') { - (console.error || console.log).call(console, arguments[0]); - arguments[arguments.length - 1].reject.apply(arguments[arguments.length - 1], arguments); - } else { - if (arguments[0] instanceof Error) { - Guard.raise(arguments[0]); - } else { - Guard.raise(new Exception("DEFAULT ERROR CALLBACK!", "DefaultError", arguments)); - } - } -}; -$data.defaultSuccessCallback = function () { /*console.log('DEFAULT SUCCES CALLBACK');*/ }; -$data.defaultNotifyCallback = function () { /*console.log('DEFAULT NOTIFY CALLBACK');*/ }; - -$data.typeSystem = { - __namespace: true, - /*inherit: function (ctor, baseType) { - var proto = new baseType(); - ctor.prototype = $.extend(proto, ctor.prototype); - //console.dir(proto); - ctor.prototype.base = new baseType(); - //console.dir(ctor.prototype.base); - ctor.prototype.constructor = ctor; - return ctor; - },*/ - //mix: function (type, mixin) { - // type.prototype = $.extend(type.prototype || {}, mixin.prototype || {}); - // type.mixins = type.mixins || []; - // type.mixins.push(mixin); - // return type; - //}, - extend: function (target) { - /// - /// Extends an object with properties of additional parameters. - /// - /// - /// Object that will be extended. - /// Object to extend target with. - /// Object to extend target with. - /// - /// - if (typeof target !== 'object' && typeof target !== 'function') - Guard.raise('Target must be object or function'); - - for (var i = 1; i < arguments.length; i++) { - var obj = arguments[i]; - if (obj === null || typeof obj === 'undefined') - continue; - for (key in obj) { - target[key] = obj[key]; - } - } - return target; - }, - createCallbackSetting: function (callBack, defaultSetting) { - var setting = { - success: $data.defaultSuccessCallback, - error: $data.defaultErrorCallback, - notify: $data.defaultNotifyCallback - }; - - if (defaultSetting != undefined && defaultSetting != null) { - setting = defaultSetting; - } - - var result; - if (callBack == null || callBack == undefined) { - result = setting; - - } else if (typeof callBack == 'function') { - result = this.extend(setting, { success: callBack }); - - } else { - result = this.extend(setting, callBack); - } - - function wrapCode(fn) { var t = this; function r() { fn.apply(t, arguments); fn = function () { } } return r; } - - if (typeof result.error === 'function') - result.error = wrapCode(result.error); - - return result; - }, - createCtorParams: function (source, indexes, thisObj) { - ///Paramerter array - /// - /// - if (indexes) { - var paramArray = []; - for (var i = 0, l = indexes.length; i < l; i++) { - var item = i; - if (indexes[item] instanceof ConstructorParameter) - paramArray.push(source[indexes[item].paramIndex]); - else if (typeof indexes[item] === "function") - paramArray.push(indexes[item].apply(thisObj)); - else - paramArray.push(indexes[item]); - } - return paramArray; - } - return source; - }, - writePropertyValues: function (obj) { - if (obj && obj.getType && obj.getType().memberDefinitions) { - this.writeProperties(obj, obj.getType().memberDefinitions.asArray().filter( - function (md) { return (md.kind == "property" || md.kind == "navProperty" || md.kind == "complexProperty") && !md.prototypeProperty; } - )); - } - }, - writeProperties: function (obj, members) { - var defines = {}; - for (var i = 0, l = members.length; i < l; i++) { - var memDef = members[i]; - defines[memDef.name] = memDef.createPropertyDescriptor(null, memDef.value); - } - - Object.defineProperties(obj, defines); - - }, - writeProperty: function (obj, member, value) { - var memDef = typeof member === 'string' ? obj.getType().memberDefinitions.getMember(member) : member; - if (memDef) { - var propDef = memDef.createPropertyDescriptor(null, value); - //////OPTIMIZATION - Object.defineProperty(obj, memDef.name, propDef); - } - } -}; - -$data.debug = function () { - (console.debug || console.log).apply(console, arguments); -}; - -$data.debugWith = function () { - var cArgs = arguments; - return function (r) { - (console.debug || console.log).apply(console, cArgs); - if ((typeof Error !== 'undefined' && r instanceof Error) || - (typeof Exception !== 'undefined' && r instanceof Exception)) { - (console.error || console.log).apply(console, arguments); - } else { - (console.debug || console.log).apply(console, arguments); - } - } -}; - -$data.fdebug = { - success: $data.debugWith('success'), - error: $data.debugWith('error') -}; -$data.Number = typeof Number !== 'undefined' ? Number : function JayNumber() { }; -$data.Date = typeof Date !== 'undefined' ? Date : function JayDate() { }; -$data.String = typeof String !== 'undefined' ? String : function JayString() { }; -$data.Boolean = typeof Boolean !== 'undefined' ? Boolean : function JayBoolean() { }; -$data.Array = typeof Array !== 'undefined' ? Array : function JayArray() { }; -$data.Object = typeof Object !== 'undefined' ? Object : function JayObject() { }; -$data.Function = Function; - -$data.Byte = function JayByte() { }; -$data.SByte = function JaySByte() { }; -$data.Decimal = function JayDecimal() { }; -$data.Float = $data.Single = function JayFloat() { }; -$data.Integer = function JayInteger() { }; -$data.Int16 = function JayInt16(v) { }; -$data.Int32 = function JayInt32() { }; -$data.Int64 = function JayInt64(v) { }; -$data.ObjectID = typeof $data.mongoDBDriver !== 'undefined' && typeof $data.mongoDBDriver.ObjectID !== 'undefined' ? $data.mongoDBDriver.ObjectID : function JayObjectID() { }; -$data.Time = function JayTime() { }; -$data.DateTimeOffset = function JayDateTimeOffset(val) { - this.value = val; -}; -$data.DateTimeOffset.prototype.toJSON = function () { - return this.value instanceof Date ? this.value.toISOString() : this.value; -}; - -$data.Container.registerType(["$data.Number", "number", "JayNumber", "double"], $data.Number); -$data.Container.registerType(["$data.Integer", "int", "integer", "JayInteger"], $data.Integer); -$data.Container.registerType(["$data.Int32", "int32", "JayInt32"], $data.Int32); -$data.Container.registerType(["$data.Byte", "byte", "JayByte"], $data.Byte); -$data.Container.registerType(["$data.SByte", "sbyte", "JaySByte"], $data.SByte); -$data.Container.registerType(["$data.Decimal", "decimal", "JayDecimal"], $data.Decimal); -$data.Container.registerType(["$data.Float", "$data.Single", "float", "single", "JayFloat"], $data.Float); -$data.Container.registerType(["$data.Int16", "int16", "word", "JayInt16"], $data.Int16); -$data.Container.registerType(["$data.Int64", "int64", "long", "JayInt64"], $data.Int64); -$data.Container.registerType(["$data.String", "string", "text", "character", "JayString"], $data.String); -$data.Container.registerType(["$data.Array", "array", "Array", "[]", "JayArray"], $data.Array, function () { - return $data.Array.apply(undefined, arguments); -}); -$data.Container.registerType(["$data.Date", "datetime", "date", "JayDate"], $data.Date); -$data.Container.registerType(["$data.Time", "time", "JayTime"], $data.Time); -$data.Container.registerType(["$data.DateTimeOffset", "offset", "datetimeoffset", "JayDateTimeOffset"], $data.DateTimeOffset); -$data.Container.registerType(["$data.Boolean", "bool", "boolean", "JayBoolean"], $data.Boolean); -$data.Container.registerType(["$data.Object", "Object", "object", "{}", "JayObject"], $data.Object); -$data.Container.registerType(["$data.Function", "Function", "function"], $data.Function); -$data.Container.registerType(['$data.ObjectID', 'ObjectID', 'objectId', 'objectid', 'ID', 'Id', 'id', 'JayObjectID'], $data.ObjectID); -$data.Class.define('$data.TraceBase', null, null, { - log: function () { }, - warn: function () { }, - error: function () { } -}); - -$data.Trace = new $data.TraceBase(); -$data.Class.define('$data.Logger', $data.TraceBase, null, { - log: function () { - Array.prototype.unshift.call(arguments, this.getDateFormat()); - console.log.apply(console, arguments); - }, - warn: function () { - Array.prototype.unshift.call(arguments, this.getDateFormat()); - console.warn.apply(console, arguments); - }, - error: function () { - Array.prototype.unshift.call(arguments, this.getDateFormat()); - console.error.apply(console, arguments); - }, - - getDateFormat: function () { - var date = new Date(); - return date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds() + '.' + date.getMilliseconds(); - } -}); -$data.Number = typeof Number !== 'undefined' ? Number : function JayNumber() { }; -$data.Date = typeof Date !== 'undefined' ? Date : function JayDate() { }; -$data.String = typeof String !== 'undefined' ? String : function JayString() { }; -$data.Boolean = typeof Boolean !== 'undefined' ? Boolean : function JayBoolean() { }; -$data.Array = typeof Array !== 'undefined' ? Array : function JayArray() { }; -$data.Object = typeof Object !== 'undefined' ? Object : function JayObject() { }; -$data.Function = Function; - -$data.Byte = function JayByte() { }; -$data.SByte = function JaySByte() { }; -$data.Decimal = function JayDecimal() { }; -$data.Float = $data.Single = function JayFloat() { }; -$data.Integer = function JayInteger() { }; -$data.Int16 = function JayInt16(v) { }; -$data.Int32 = function JayInt32() { }; -$data.Int64 = function JayInt64(v) { }; -$data.ObjectID = typeof $data.mongoDBDriver !== 'undefined' && typeof $data.mongoDBDriver.ObjectID !== 'undefined' ? $data.mongoDBDriver.ObjectID : function JayObjectID() { }; -$data.Time = function JayTime() { }; -$data.DateTimeOffset = function JayDateTimeOffset(val) { - this.value = val; -}; -$data.DateTimeOffset.prototype.toJSON = function () { - return this.value instanceof Date ? this.value.toISOString() : this.value; -}; - -$data.Container.registerType(["$data.Number", "number", "JayNumber", "double"], $data.Number); -$data.Container.registerType(["$data.Integer", "int", "integer", "JayInteger"], $data.Integer); -$data.Container.registerType(["$data.Int32", "int32", "JayInt32"], $data.Int32); -$data.Container.registerType(["$data.Byte", "byte", "JayByte"], $data.Byte); -$data.Container.registerType(["$data.SByte", "sbyte", "JaySByte"], $data.SByte); -$data.Container.registerType(["$data.Decimal", "decimal", "JayDecimal"], $data.Decimal); -$data.Container.registerType(["$data.Float", "$data.Single", "float", "single", "JayFloat"], $data.Float); -$data.Container.registerType(["$data.Int16", "int16", "word", "JayInt16"], $data.Int16); -$data.Container.registerType(["$data.Int64", "int64", "long", "JayInt64"], $data.Int64); -$data.Container.registerType(["$data.String", "string", "text", "character", "JayString"], $data.String); -$data.Container.registerType(["$data.Array", "array", "Array", "[]", "JayArray"], $data.Array, function () { - return $data.Array.apply(undefined, arguments); -}); -$data.Container.registerType(["$data.Date", "datetime", "date", "JayDate"], $data.Date); -$data.Container.registerType(["$data.Time", "time", "JayTime"], $data.Time); -$data.Container.registerType(["$data.DateTimeOffset", "offset", "datetimeoffset", "JayDateTimeOffset"], $data.DateTimeOffset); -$data.Container.registerType(["$data.Boolean", "bool", "boolean", "JayBoolean"], $data.Boolean); -$data.Container.registerType(["$data.Object", "Object", "object", "{}", "JayObject"], $data.Object); -$data.Container.registerType(["$data.Function", "Function", "function"], $data.Function); -$data.Container.registerType(['$data.ObjectID', 'ObjectID', 'objectId', 'objectid', 'ID', 'Id', 'id', 'JayObjectID'], $data.ObjectID); -/* $data.SimpleBase */ -$data.SimpleBase = function SimpleBase(data) { - if (typeof data === 'object' && data) { - if (Array.isArray(this.constructor.validMembers)) { - for (var i = 0; i < this.constructor.validMembers.length; i++) { - var name = this.constructor.validMembers[i]; - - if (data[name] !== undefined) { - this[name] = data[name]; - } - } - - } else { - delete data.type; - $data.typeSystem.extend(this, data); - } - } -} -$data.SimpleBase.registerType = function (name, type, base) { - base = base || $data.SimpleBase; - - type.type = name; - type.prototype = Object.create(base.prototype); - type.prototype.constructor = type; -} -$data.Container.registerType(['$data.SimpleBase', 'SimpleBase'], $data.SimpleBase);$data.Geospatial = function Geospatial() { - this.type = this.constructor.type; - if (Array.isArray(this.constructor.validMembers)) { - for (var i = 0; i < this.constructor.validMembers.length; i++) { - var name = this.constructor.validMembers[i]; - this[name] = undefined; - } - } - - $data.SimpleBase.apply(this, arguments); - this.type = this.constructor.type || 'Unknown'; -}; -$data.SimpleBase.registerType('Geospatial', $data.Geospatial); -$data.Container.registerType(['$data.Geospatial', 'Geospatial'], $data.Geospatial); - -$data.point = function (arg) { - if (arg && arg.crs) { - if (arg.crs.properties && arg.crs.properties.name === $data.GeometryBase.defaultCrs.properties.name) { - return new $data.GeometryPoint(arg); - } else { - return new $data.GeographyPoint(arg); - } - } else if(arg) { - if ('x' in arg && 'y' in arg) { - return new $data.GeometryPoint(arg.x, arg.y); - } else if ('longitude' in arg && 'latitude' in arg) { - return new $data.GeographyPoint(arg.longitude, arg.latitude); - } else if ('lng' in arg && 'lat' in arg) { - return new $data.GeographyPoint(arg.lng, arg.lat); - } - } -}; -/* $data.GeographyBase */ -$data.GeographyBase = function GeographyBase() { - $data.Geospatial.apply(this, arguments); - - this.crs = $data.GeographyBase.defaultCrs; - $data.GeographyBase.validateGeoJSON(this); -}; - -$data.GeographyBase.defaultCrs = { - properties: { - name: 'EPSG:4326' - }, - type: 'name' -}; - -$data.GeographyBase.parseFromString = function (strData) { - var lparenIdx = strData.indexOf('('); - if(lparenIdx >= 0){ - var name = strData.substring(0, lparenIdx).toLowerCase(); - var type = $data.GeographyBase.registered[name]; - - if (type && type.parseFromString && type != $data.GeographyBase) { - return type.parseFromString(strData); - } else { - Guard.raise(new Exception('parseFromString', 'Not Implemented', strData)); - } - } -}; -$data.GeographyBase.stringifyToUrl = function (geoData) { - if (geoData instanceof $data.GeographyBase && geoData.constructor && geoData.constructor.stringifyToUrl) { - return geoData.constructor.stringifyToUrl(geoData); - } else if (geoData instanceof $data.GeographyBase && geoData.constructor && Array.isArray(geoData.constructor.validMembers) && geoData.constructor.validMembers[0] === 'coordinates') { - var data = "geography'" + geoData.type.toUpperCase() + '('; - function buildArray(d, context) { - if (Array.isArray(d[0])) { - - for (var i = 0; i < d.length; i++) { - if (i > 0) data += ','; - if (Array.isArray(d[i][0])) - data += '('; - - buildArray(d[i]); - - if (Array.isArray(d[i][0])) - data += ')'; - } - - } else { - data += d.join(' '); - } - } - buildArray(geoData.coordinates, data); - - data += ")'"; - return data; - } else { - Guard.raise(new Exception('stringifyToUrl on instance type', 'Not Implemented', geoData)); - } -}; -$data.GeographyBase.registerType = function (name, type, base) { - $data.SimpleBase.registerType(name, type, base || $data.GeographyBase); - - $data.GeographyBase.registered = $data.GeographyBase.registered || {}; - $data.GeographyBase.registered[name.toLowerCase()] = type; -}; -$data.GeographyBase.validateGeoJSON = function (geoData) { - var type = geoData.type; - if (type) { - var geoType = $data.GeographyBase.registered[type.toLowerCase()]; - if (typeof geoType.validateGeoJSON === 'function') { - var isValid = geoType.validateGeoJSON(geoData); - if (isValid) { - return isValid; - } else { - Guard.raise(new Exception("Invalid '" + type + "' format!", 'Format Exception', geoData)); - } - } - } - console.log('GeoJSON validation missing', geoData); - return; -}; -$data.SimpleBase.registerType('GeographyBase', $data.GeographyBase, $data.Geospatial); -$data.Container.registerType(['$data.GeographyBase'], $data.GeographyBase); - -/* $data.GeographyPoint */ -$data.GeographyPoint = function GeographyPoint(lon, lat) { - if (lon && typeof lon === 'object' && Array.isArray(lon)) { - $data.GeographyBase.call(this, { coordinates: lon }); - } else if (lon && typeof lon === 'object' && ('longitude' in lon || 'latitude' in lon)) { - $data.GeographyBase.call(this, { coordinates: [lon.longitude, lon.latitude] }); - } else if (lon && typeof lon === 'object' && ('lng' in lon || 'lat' in lon)) { - $data.GeographyBase.call(this, { coordinates: [lon.lng, lon.lat] }); - } else if (lon && typeof lon === 'object') { - $data.GeographyBase.call(this, lon); - } else { - $data.GeographyBase.call(this, { coordinates: [lon || 0, lat || 0] }); - } -}; -$data.GeographyPoint.validateGeoJSON = function (geoData) { - return geoData && - Array.isArray(geoData.coordinates) && - geoData.coordinates.length == 2 && - typeof geoData.coordinates[0] === 'number' && - typeof geoData.coordinates[1] === 'number'; -}; -$data.GeographyPoint.parseFromString = function (strData) { - var data = strData.substring(strData.indexOf('(') + 1, strData.lastIndexOf(')')); - var values = data.split(' '); - - return new $data.GeographyPoint(parseFloat(values[0]), parseFloat(values[1])); -}; -$data.GeographyPoint.validMembers = ['coordinates']; -$data.GeographyBase.registerType('Point', $data.GeographyPoint); -Object.defineProperty($data.GeographyPoint.prototype, 'longitude', { get: function () { return this.coordinates[0]; }, set: function (v) { this.coordinates[0] = v; } }); -Object.defineProperty($data.GeographyPoint.prototype, 'latitude', { get: function () { return this.coordinates[1]; }, set: function (v) { this.coordinates[1] = v; } }); -$data.Container.registerType(['$data.GeographyPoint', 'GeographyPoint', '$data.Geography', 'Geography', 'geography', 'geo'], $data.GeographyPoint); -$data.Geography = $data.GeographyPoint; - -/* $data.GeographyLineString */ -$data.GeographyLineString = function GeographyLineString(data) { - if (Array.isArray(data)) { - $data.GeographyBase.call(this, { coordinates: data }); - } else { - $data.GeographyBase.call(this, data); - } -}; -$data.GeographyLineString.validateGeoJSON = function (geoData) { - var isValid = geoData && - Array.isArray(geoData.coordinates); - - for (var i = 0; isValid && i < geoData.coordinates.length; i++) { - var point = geoData.coordinates[i]; - isValid = isValid && - Array.isArray(point) && - point.length == 2 && - typeof point[0] === 'number' && - typeof point[1] === 'number'; - } - - return isValid; -}; -$data.GeographyLineString.validMembers = ['coordinates']; -$data.GeographyBase.registerType('LineString', $data.GeographyLineString); -$data.Container.registerType(['$data.GeographyLineString', 'GeographyLineString'], $data.GeographyLineString); - -/* $data.GeographyPolygon */ -$data.GeographyPolygon = function GeographyPolygon(data) { - if (typeof data === 'object' && (('topLeft' in data && 'bottomRight' in data) || ('topRight' in data && 'bottomLeft' in data))) { - var tl, tr, bl, br; - - if ('topLeft' in data && 'bottomRight' in data) { - tl = data.topLeft instanceof $data.GeographyPoint ? data.topLeft : new $data.GeographyPoint(data.topLeft); - br = data.bottomRight instanceof $data.GeographyPoint ? data.bottomRight : new $data.GeographyPoint(data.bottomRight); - tr = new $data.GeographyPoint([br.coordinates[0], tl.coordinates[1]]); - bl = new $data.GeographyPoint([tl.coordinates[0], br.coordinates[1]]); - } else { - tr = data.topRight instanceof $data.GeographyPoint ? data.topRight : new $data.GeographyPoint(data.topRight); - bl = data.bottomLeft instanceof $data.GeographyPoint ? data.bottomLeft : new $data.GeographyPoint(data.bottomLeft); - tl = new $data.GeographyPoint([bl.coordinates[0], tr.coordinates[1]]); - br = new $data.GeographyPoint([tr.coordinates[0], bl.coordinates[1]]); - } - - var coordinates = []; - coordinates.push([].concat(tl.coordinates)); - coordinates.push([].concat(tr.coordinates)); - coordinates.push([].concat(br.coordinates)); - coordinates.push([].concat(bl.coordinates)); - coordinates.push([].concat(tl.coordinates)); - - $data.GeographyBase.call(this, { coordinates: [coordinates] }); - - }else if (Array.isArray(data)) { - $data.GeographyBase.call(this, { coordinates: data }); - } else { - $data.GeographyBase.call(this, data); - } -}; -$data.GeographyPolygon.validateGeoJSON = function (geoData) { - var isValid = geoData && - Array.isArray(geoData.coordinates); - - for (var i = 0; isValid && i < geoData.coordinates.length; i++) { - var polygon = geoData.coordinates[i]; - var isValid = isValid && Array.isArray(polygon); - - for (var j = 0; isValid && j < polygon.length; j++) { - var point = polygon[j]; - - isValid = isValid && - Array.isArray(point) && - point.length == 2 && - typeof point[0] === 'number' && - typeof point[1] === 'number'; - } - } - - return isValid; -}; -$data.GeographyPolygon.parseFromString = function (strData) { - var data = strData.substring(strData.indexOf('(') + 1, strData.lastIndexOf(')')); - var rings = data.substring(data.indexOf('(') + 1, data.lastIndexOf(')')).split('),('); - - var data = []; - for (var i = 0; i < rings.length; i++) { - var polyPoints = []; - var pairs = rings[i].split(','); - for (var j = 0; j < pairs.length; j++) { - var values = pairs[j].split(' '); - - polyPoints.push([parseFloat(values[0]), parseFloat(values[1])]); - } - data.push(polyPoints); - } - - return new $data.GeographyPolygon(data); -}; -$data.GeographyPolygon.validMembers = ['coordinates']; -$data.GeographyBase.registerType('Polygon', $data.GeographyPolygon); -$data.Container.registerType(['$data.GeographyPolygon', 'GeographyPolygon'], $data.GeographyPolygon); - -/* $data.GeographyMultiPoint */ -$data.GeographyMultiPoint = function GeographyMultiPoint(data) { - if (Array.isArray(data)) { - $data.GeographyBase.call(this, { coordinates: data }); - } else { - $data.GeographyBase.call(this, data); - } -}; -$data.GeographyMultiPoint.validateGeoJSON = function (geoData) { - var isValid = geoData && - Array.isArray(geoData.coordinates); - - for (var i = 0; isValid && i < geoData.coordinates.length; i++) { - var point = geoData.coordinates[i]; - isValid = isValid && - Array.isArray(point) && - point.length == 2 && - typeof point[0] === 'number' && - typeof point[1] === 'number'; - } - - return isValid; -}; -$data.GeographyMultiPoint.validMembers = ['coordinates']; -$data.GeographyBase.registerType('MultiPoint', $data.GeographyMultiPoint); -$data.Container.registerType(['$data.GeographyMultiPoint', 'GeographyMultiPoint'], $data.GeographyMultiPoint); - -/* $data.GeographyMultiLineString */ -$data.GeographyMultiLineString = function GeographyMultiLineString(data) { - if (Array.isArray(data)) { - $data.GeographyBase.call(this, { coordinates: data }); - } else { - $data.GeographyBase.call(this, data); - } -}; -$data.GeographyMultiLineString.validateGeoJSON = function (geoData) { - var isValid = geoData && - Array.isArray(geoData.coordinates); - - for (var i = 0; isValid && i < geoData.coordinates.length; i++) { - var polygon = geoData.coordinates[i]; - var isValid = isValid && Array.isArray(polygon); - - for (var j = 0; isValid && j < polygon.length; j++) { - var point = polygon[j]; - - isValid = isValid && - Array.isArray(point) && - point.length == 2 && - typeof point[0] === 'number' && - typeof point[1] === 'number'; - } - } - - return isValid; -}; -$data.GeographyMultiLineString.validMembers = ['coordinates']; -$data.GeographyBase.registerType('MultiLineString', $data.GeographyMultiLineString); -$data.Container.registerType(['$data.GeographyMultiLineString', 'GeographyMultiLineString'], $data.GeographyMultiLineString); - -/* $data.GeographyMultiPolygon */ -$data.GeographyMultiPolygon = function GeographyMultiPolygon(data) { - if (Array.isArray(data)) { - $data.GeographyBase.call(this, { coordinates: data }); - } else { - $data.GeographyBase.call(this, data); - } -}; -$data.GeographyMultiPolygon.validateGeoJSON = function (geoData) { - var isValid = geoData && - Array.isArray(geoData.coordinates); - - for (var k = 0; isValid && k < geoData.coordinates.length; k++) { - var polygons = geoData.coordinates[k]; - var isValid = isValid && Array.isArray(polygons); - - for (var i = 0; isValid && i < polygons.length; i++) { - var polygon = polygons[i]; - var isValid = isValid && Array.isArray(polygon); - - for (var j = 0; isValid && j < polygon.length; j++) { - var point = polygon[j]; - - isValid = isValid && - Array.isArray(point) && - point.length == 2 && - typeof point[0] === 'number' && - typeof point[1] === 'number'; - } - } - } - - return isValid; -}; -$data.GeographyMultiPolygon.validMembers = ['coordinates']; -$data.GeographyBase.registerType('MultiPolygon', $data.GeographyMultiPolygon); -$data.Container.registerType(['$data.GeographyMultiPolygon', 'GeographyMultiPolygon'], $data.GeographyMultiPolygon); - -/* $data.GeographyCollection */ -$data.GeographyCollection = function GeographyCollection(data) { - if (Array.isArray(data)) { - $data.GeographyBase.call(this, { geometries: data }); - } else { - $data.GeographyBase.call(this, data); - } -}; -$data.GeographyCollection.validateGeoJSON = function (geoData) { - var isValid = geoData && - Array.isArray(geoData.geometries); - - for (var i = 0; isValid && i < geoData.geometries.length; i++) { - var geometry = geoData.geometries[i]; - try { - isValid = isValid && $data.GeographyBase.validateGeoJSON(geometry); - } catch (e) { - isValid = false; - } - } - - return isValid; -}; -$data.GeographyCollection.validMembers = ['geometries']; -$data.GeographyBase.registerType('GeometryCollection', $data.GeographyCollection); -$data.Container.registerType(['$data.GeographyCollection', 'GeographyCollection'], $data.GeographyCollection); - - -/* converters */ -$data.Container.registerConverter($data.GeographyPoint, $data.Object, function (value) { - return value ? new $data.GeographyPoint(value) : value; -}); -$data.Container.registerConverter($data.GeographyLineString, $data.Object, function (value) { - return value ? new $data.GeographyLineString(value) : value; -}); -$data.Container.registerConverter($data.GeographyPolygon, $data.Object, function (value) { - return value ? new $data.GeographyPolygon(value) : value; -}); -$data.Container.registerConverter($data.GeographyMultiPoint, $data.Object, function (value) { - return value ? new $data.GeographyMultiPoint(value) : value; -}); -$data.Container.registerConverter($data.GeographyMultiLineString, $data.Object, function (value) { - return value ? new $data.GeographyMultiLineString(value) : value; -}); -$data.Container.registerConverter($data.GeographyMultiPolygon, $data.Object, function (value) { - return value ? new $data.GeographyMultiPolygon(value) : value; -}); -$data.Container.registerConverter($data.GeographyCollection, $data.Object, function (value) { - return value ? new $data.GeographyCollection(value) : value; -}); -/* $data.Geometry */ -$data.GeometryBase = function GeometryBase() { - $data.Geospatial.apply(this, arguments); - - this.crs = $data.GeometryBase.defaultCrs; - $data.GeometryBase.validateGeoJSON(this); -}; - -$data.GeometryBase.defaultCrs = { - properties: { - name: 'EPSG:0' - }, - type: 'name' -}; - -$data.GeometryBase.parseFromString = function (strData) { - var lparenIdx = strData.indexOf('('); - if (lparenIdx >= 0) { - var name = strData.substring(0, lparenIdx).toLowerCase(); - var type = $data.GeometryBase.registered[name]; - - if (type && type.parseFromString && type != $data.GeometryBase) { - return type.parseFromString(strData); - } else { - Guard.raise(new Exception('parseFromString', 'Not Implemented', strData)); - } - } -}; -$data.GeometryBase.stringifyToUrl = function (geoData) { - if (geoData instanceof $data.GeometryBase && geoData.constructor && geoData.constructor.stringifyToUrl) { - return geoData.constructor.stringifyToUrl(geoData); - } else if (geoData instanceof $data.GeometryBase && geoData.constructor && Array.isArray(geoData.constructor.validMembers) && geoData.constructor.validMembers[0] === 'coordinates') { - var data = "geometry'" + geoData.type.toUpperCase() + '('; - function buildArray(d, context) { - if (Array.isArray(d[0])) { - - for (var i = 0; i < d.length; i++) { - if (i > 0) data += ','; - if (Array.isArray(d[i][0])) - data += '('; - - buildArray(d[i]); - - if (Array.isArray(d[i][0])) - data += ')'; - } - - } else { - data += d.join(' '); - } - } - buildArray(geoData.coordinates, data); - - data += ")'"; - return data; - } else { - Guard.raise(new Exception('stringifyToUrl on instance type', 'Not Implemented', geoData)); - } -}; -$data.GeometryBase.registerType = function (name, type, base) { - $data.SimpleBase.registerType(name, type, base || $data.GeometryBase); - - $data.GeometryBase.registered = $data.GeometryBase.registered || {}; - $data.GeometryBase.registered[name.toLowerCase()] = type; -}; -$data.GeometryBase.validateGeoJSON = function (geoData) { - var type = geoData.type; - if (type) { - var geoType = $data.GeometryBase.registered[type.toLowerCase()]; - if (typeof geoType.validateGeoJSON === 'function') { - var isValid = geoType.validateGeoJSON(geoData); - if (isValid) { - return isValid; - } else { - Guard.raise(new Exception("Invalid '" + type + "' format!", 'Format Exception', geoData)); - } - } - } - console.log('GeoJSON validation missing', geoData); - return; -}; -$data.SimpleBase.registerType('GeometryBase', $data.GeometryBase, $data.Geospatial); -$data.Container.registerType(['$data.GeometryBase'], $data.GeometryBase); - -/* $data.GeometryPoint */ -$data.GeometryPoint = function GeometryPoint(x, y) { - var param = x; - if (param && typeof param === 'object' && Array.isArray(param)) { - $data.GeometryBase.call(this, { coordinates: param }); - } else if (param && typeof param === 'object' && ('x' in param || 'y' in param)) { - $data.GeometryBase.call(this, { coordinates: [param.x, param.y] }); - } else if (param && typeof param === 'object') { - $data.GeometryBase.call(this, param); - } else { - $data.GeometryBase.call(this, { coordinates: [x || 0, y || 0] }); - } -}; -$data.GeometryPoint.validateGeoJSON = function (geoData) { - return geoData && - Array.isArray(geoData.coordinates) && - geoData.coordinates.length == 2 && - typeof geoData.coordinates[0] === 'number' && - typeof geoData.coordinates[1] === 'number'; -}; -$data.GeometryPoint.parseFromString = function (strData) { - var data = strData.substring(strData.indexOf('(') + 1, strData.lastIndexOf(')')); - var values = data.split(' '); - - return new $data.GeometryPoint(parseFloat(values[0]), parseFloat(values[1])); -}; -$data.GeometryPoint.validMembers = ['coordinates']; -$data.GeometryBase.registerType('Point', $data.GeometryPoint); -Object.defineProperty($data.GeometryPoint.prototype, 'x', { get: function () { return this.coordinates[0]; }, set: function (v) { this.coordinates[0] = v; } }); -Object.defineProperty($data.GeometryPoint.prototype, 'y', { get: function () { return this.coordinates[1]; }, set: function (v) { this.coordinates[1] = v; } }); -$data.Container.registerType(['$data.GeometryPoint', 'GeometryPoint'], $data.GeometryPoint); - -/* $data.GeometryLineString */ -$data.GeometryLineString = function GeometryLineString(data) { - if (Array.isArray(data)) { - $data.GeometryBase.call(this, { coordinates: data }); - } else { - $data.GeometryBase.call(this, data); - } -}; -$data.GeometryLineString.validateGeoJSON = function (geoData) { - var isValid = geoData && - Array.isArray(geoData.coordinates); - - for (var i = 0; isValid && i < geoData.coordinates.length; i++) { - var point = geoData.coordinates[i]; - isValid = isValid && - Array.isArray(point) && - point.length == 2 && - typeof point[0] === 'number' && - typeof point[1] === 'number'; - } - - return isValid; -}; -$data.GeometryLineString.validMembers = ['coordinates']; -$data.GeometryBase.registerType('LineString', $data.GeometryLineString); -$data.Container.registerType(['$data.GeometryLineString', 'GeometryLineString'], $data.GeometryLineString); - -/* $data.GeometryPolygon */ -$data.GeometryPolygon = function GeometryPolygon(data) { - if (typeof data === 'object' && (('topLeft' in data && 'bottomRight' in data) || ('topRight' in data && 'bottomLeft' in data))) { - var tl, tr, bl, br; - - if ('topLeft' in data && 'bottomRight' in data) { - tl = data.topLeft instanceof $data.GeometryPoint ? data.topLeft : new $data.GeometryPoint(data.topLeft); - br = data.bottomRight instanceof $data.GeometryPoint ? data.bottomRight : new $data.GeometryPoint(data.bottomRight); - tr = new $data.GeometryPoint([br.coordinates[0], tl.coordinates[1]]); - bl = new $data.GeometryPoint([tl.coordinates[0], br.coordinates[1]]); - } else { - tr = data.topRight instanceof $data.GeometryPoint ? data.topRight : new $data.GeometryPoint(data.topRight); - bl = data.bottomLeft instanceof $data.GeometryPoint ? data.bottomLeft : new $data.GeometryPoint(data.bottomLeft); - tl = new $data.GeometryPoint([bl.coordinates[0], tr.coordinates[1]]); - br = new $data.GeometryPoint([tr.coordinates[0], bl.coordinates[1]]); - } - - var coordinates = []; - coordinates.push([].concat(tl.coordinates)); - coordinates.push([].concat(tr.coordinates)); - coordinates.push([].concat(br.coordinates)); - coordinates.push([].concat(bl.coordinates)); - coordinates.push([].concat(tl.coordinates)); - - $data.GeometryBase.call(this, { coordinates: [coordinates] }); - - }else if (Array.isArray(data)) { - $data.GeometryBase.call(this, { coordinates: data }); - } else { - $data.GeometryBase.call(this, data); - } -}; -$data.GeometryPolygon.validateGeoJSON = function (geoData) { - var isValid = geoData && - Array.isArray(geoData.coordinates); - - for (var i = 0; isValid && i < geoData.coordinates.length; i++) { - var polygon = geoData.coordinates[i]; - var isValid = isValid && Array.isArray(polygon); - - for (var j = 0; isValid && j < polygon.length; j++) { - var point = polygon[j]; - - isValid = isValid && - Array.isArray(point) && - point.length == 2 && - typeof point[0] === 'number' && - typeof point[1] === 'number'; - } - } - - return isValid; -}; -$data.GeometryPolygon.parseFromString = function (strData) { - var data = strData.substring(strData.indexOf('(') + 1, strData.lastIndexOf(')')); - var rings = data.substring(data.indexOf('(') + 1, data.lastIndexOf(')')).split('),('); - - var data = []; - for (var i = 0; i < rings.length; i++) { - var polyPoints = []; - var pairs = rings[i].split(','); - for (var j = 0; j < pairs.length; j++) { - var values = pairs[j].split(' '); - - polyPoints.push([parseFloat(values[0]), parseFloat(values[1])]); - } - data.push(polyPoints); - } - - return new $data.GeometryPolygon(data); -}; -$data.GeometryPolygon.validMembers = ['coordinates']; -$data.GeometryBase.registerType('Polygon', $data.GeometryPolygon); -$data.Container.registerType(['$data.GeometryPolygon', 'GeometryPolygon'], $data.GeometryPolygon); - -/* $data.GeometryMultiPoint */ -$data.GeometryMultiPoint = function GeometryMultiPoint(data) { - if (Array.isArray(data)) { - $data.GeometryBase.call(this, { coordinates: data }); - } else { - $data.GeometryBase.call(this, data); - } -}; -$data.GeometryMultiPoint.validateGeoJSON = function (geoData) { - var isValid = geoData && - Array.isArray(geoData.coordinates); - - for (var i = 0; isValid && i < geoData.coordinates.length; i++) { - var point = geoData.coordinates[i]; - isValid = isValid && - Array.isArray(point) && - point.length == 2 && - typeof point[0] === 'number' && - typeof point[1] === 'number'; - } - - return isValid; -}; -$data.GeometryMultiPoint.validMembers = ['coordinates']; -$data.GeometryBase.registerType('MultiPoint', $data.GeometryMultiPoint); -$data.Container.registerType(['$data.GeometryMultiPoint', 'GeometryMultiPoint'], $data.GeometryMultiPoint); - -/* $data.GeometryMultiLineString */ -$data.GeometryMultiLineString = function GeometryMultiLineString(data) { - if (Array.isArray(data)) { - $data.GeometryBase.call(this, { coordinates: data }); - } else { - $data.GeometryBase.call(this, data); - } -}; -$data.GeometryMultiLineString.validateGeoJSON = function (geoData) { - var isValid = geoData && - Array.isArray(geoData.coordinates); - - for (var i = 0; isValid && i < geoData.coordinates.length; i++) { - var polygon = geoData.coordinates[i]; - var isValid = isValid && Array.isArray(polygon); - - for (var j = 0; isValid && j < polygon.length; j++) { - var point = polygon[j]; - - isValid = isValid && - Array.isArray(point) && - point.length == 2 && - typeof point[0] === 'number' && - typeof point[1] === 'number'; - } - } - - return isValid; -}; -$data.GeometryMultiLineString.validMembers = ['coordinates']; -$data.GeometryBase.registerType('MultiLineString', $data.GeometryMultiLineString); -$data.Container.registerType(['$data.GeometryMultiLineString', 'GeometryMultiLineString'], $data.GeometryMultiLineString); - -/* $data.GeometryMultiPolygon */ -$data.GeometryMultiPolygon = function GeometryMultiPolygon(data) { - if (Array.isArray(data)) { - $data.GeometryBase.call(this, { coordinates: data }); - } else { - $data.GeometryBase.call(this, data); - } -}; -$data.GeometryMultiPolygon.validateGeoJSON = function (geoData) { - var isValid = geoData && - Array.isArray(geoData.coordinates); - - for (var k = 0; isValid && k < geoData.coordinates.length; k++) { - var polygons = geoData.coordinates[k]; - var isValid = isValid && Array.isArray(polygons); - - for (var i = 0; isValid && i < polygons.length; i++) { - var polygon = polygons[i]; - var isValid = isValid && Array.isArray(polygon); - - for (var j = 0; isValid && j < polygon.length; j++) { - var point = polygon[j]; - - isValid = isValid && - Array.isArray(point) && - point.length == 2 && - typeof point[0] === 'number' && - typeof point[1] === 'number'; - } - } - } - - return isValid; -}; -$data.GeometryMultiPolygon.validMembers = ['coordinates']; -$data.GeometryBase.registerType('MultiPolygon', $data.GeometryMultiPolygon); -$data.Container.registerType(['$data.GeometryMultiPolygon', 'GeometryMultiPolygon'], $data.GeometryMultiPolygon); - -/* $data.GeometryCollection */ -$data.GeometryCollection = function GeometryCollection(data) { - if (Array.isArray(data)) { - $data.GeometryBase.call(this, { geometries: data }); - } else { - $data.GeometryBase.call(this, data); - } -}; -$data.GeometryCollection.validateGeoJSON = function (geoData) { - var isValid = geoData && - Array.isArray(geoData.geometries); - - for (var i = 0; isValid && i < geoData.geometries.length; i++) { - var geometry = geoData.geometries[i]; - try { - isValid = isValid && $data.GeometryBase.validateGeoJSON(geometry); - } catch (e) { - isValid = false; - } - } - - return isValid; -}; -$data.GeometryCollection.validMembers = ['geometries']; -$data.GeometryBase.registerType('GeometryCollection', $data.GeometryCollection); -$data.Container.registerType(['$data.GeometryCollection', 'GeometryCollection'], $data.GeometryCollection); - -/* converters */ -$data.Container.registerConverter($data.GeometryPoint, $data.Object, function (value) { - return value ? new $data.GeometryPoint(value) : value; -}); -$data.Container.registerConverter($data.GeometryLineString, $data.Object, function (value) { - return value ? new $data.GeometryLineString(value) : value; -}); -$data.Container.registerConverter($data.GeometryPolygon, $data.Object, function (value) { - return value ? new $data.GeometryPolygon(value) : value; -}); -$data.Container.registerConverter($data.GeometryMultiPoint, $data.Object, function (value) { - return value ? new $data.GeometryMultiPoint(value) : value; -}); -$data.Container.registerConverter($data.GeometryMultiLineString, $data.Object, function (value) { - return value ? new $data.GeometryMultiLineString(value) : value; -}); -$data.Container.registerConverter($data.GeometryMultiPolygon, $data.Object, function (value) { - return value ? new $data.GeometryMultiPolygon(value) : value; -}); -$data.Container.registerConverter($data.GeometryCollection, $data.Object, function (value) { - return value ? new $data.GeometryCollection(value) : value; -});$data.Guid = function Guid(value) { - /// - - if (value === undefined || (typeof value === 'string' && /^[a-zA-z0-9]{8}-[a-zA-z0-9]{4}-[a-zA-z0-9]{4}-[a-zA-z0-9]{4}-[a-zA-z0-9]{12}$/.test(value))) { - this.value = value || '00000000-0000-0000-0000-000000000000'; - } else { - throw Guard.raise(new Exception('TypeError: ', 'value not convertable to $data.Guid', value)); - } -}; -$data.Container.registerType(['$data.Guid', 'Guid', 'guid'], $data.Guid); -$data.Container.registerConverter('$data.Guid', { - '$data.String': function (value) { - return value ? $data.parseGuid(value).toString() : value; - }, - '$data.Guid': function (value) { - return value ? value.toString() : value; - } -}, { - '$data.String': function (value) { - return value ? value.toString() : value; - } -}); - - -$data.Guid.prototype.toJSON = function () { - return this.value; -}; - -$data.Guid.prototype.valueOf = function () { - return this.value; -}; - -$data.Guid.prototype.toString = function () { - return this.value; -}; - -$data.Guid.NewGuid = function () { - return $data.createGuid(); -}; - -$data.parseGuid = function (guid) { - return new $data.Guid(guid); -}; - -(function () { - /*! - Math.uuid.js (v1.4) - http://www.broofa.com - mailto:robert@broofa.com - - Copyright (c) 2010 Robert Kieffer - Dual licensed under the MIT and GPL licenses. - */ - - var CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''); - - $data.createGuid = function (guidString) { - if (guidString) { - return new $data.Guid(guidString); - }; - - var len; - var chars = CHARS, uuid = [], i; - var radix = chars.length; - - if (len) { - // Compact form - for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix]; - } else { - // rfc4122, version 4 form - var r; - - // rfc4122 requires these characters - uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'; - uuid[14] = '4'; - - // Fill in random data. At i==19 set the high bits of clock sequence as - // per rfc4122, sec. 4.1.5 - for (i = 0; i < 36; i++) { - if (!uuid[i]) { - r = 0 | Math.random() * 16; - uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]; - } - } - } - - return $data.parseGuid(uuid.join('')); - }; -})();$data.Blob = function Blob(){}; - -$data.Blob.createFromHexString = function(value){ - if (value != value.match(new RegExp('[0-9a-fA-F]+'))[0]){ - Guard.raise(new Exception('TypeError: ', 'value not convertable to $data.Blob', value)); - }else{ - //if (value.length & 1) value = '0' + value; - var arr = new (typeof Buffer != 'undefined' ? Buffer : Uint8Array)(value.length >> 1); - for (var i = 0, j = 1, k = 0; i < value.length; i += 2, j += 2, k++) { - arr[k] = parseInt('0x' + value[i] + value[j], 16); - } - - return arr; - } -}; - -$data.Blob.toString = function(value){ - if (!value || !value.length) return null; - var s = ''; - for (var i = 0; i < value.length; i++){ - s += String.fromCharCode(value[i]); - } - - return s; -}; - -$data.Blob.toBase64 = function(value){ - if (!value || !value.length) return null; - return btoa($data.Blob.toString(value)); -}; - -$data.Blob.toArray = function(src){ - if (!src || !src.length) return null; - var arr = new Array(src.length); - for (var i = 0; i < src.length; i++){ - arr[i] = src[i]; - } - - return arr; -}; - -/*$data.Blob.toJSON = function(value){ - return JSON.stringify($data.Blob.toArray(value)); -};*/ - -$data.Blob.toHexString = function(value){ - if (!value || !value.length) return null; - var s = ''; - for (var i = 0; i < value.length; i++){ - s += ('00' + value[i].toString(16)).slice(-2); - } - - return s.toUpperCase(); -}; - -$data.Blob.toDataURL = function(value){ - if (!value || !value.length) return null; - return 'data:application/octet-stream;base64,' + btoa($data.Blob.toString(value)); -}; - -$data.Container.registerType(["$data.Blob", "blob", "JayBlob"], $data.Blob); -$data.Container.registerConverter('$data.Blob',{ - '$data.String': function (value){ - if (value && value.length){ - var blob = new (typeof Buffer !== 'undefined' ? Buffer : Uint8Array)(value.length); - for (var i = 0; i < value.length; i++){ - blob[i] = value.charCodeAt(i); - } - - return blob; - }else return null; - }, - '$data.Array': function(value){ - return new (typeof Buffer !== 'undefined' ? Buffer : Uint8Array)(value); - }, - '$data.Number': function(value){ - return new (typeof Buffer !== 'undefined' ? Buffer : Uint8Array)($data.packIEEE754(value, 11, 52).reverse()); - }, - '$data.Boolean': function(value){ - return new (typeof Buffer !== 'undefined' ? Buffer : Uint8Array)([value | 0]); - }, - 'default': function(value){ - if (typeof Blob !== 'undefined' && value instanceof Blob){ - var req = new XMLHttpRequest(); - req.open('GET', URL.createObjectURL(value), false); - req.responseType = 'arraybuffer'; - req.send(null); - return $data.Container.convertTo(req.response, $data.Blob); - } else if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { - return new (typeof Buffer !== 'undefined' ? Buffer : Uint8Array)(new Uint8Array(value)); - }else if (value instanceof Uint8Array){ - if (typeof Buffer !== 'undefined') return new Buffer(value); - else return value; - }else if (typeof Buffer !== 'undefined' ? value instanceof Buffer : false){ - return value; - }else if (value.buffer){ - return new (typeof Buffer !== 'undefined' ? Buffer : Uint8Array)(value); - }else if (typeof value == 'object' && value instanceof Object){ - var arr = []; - for (var i in value){ - arr[i] = value[i]; - } - if (!arr.length) throw 0; - return new (typeof Buffer !== 'undefined' ? Buffer : Uint8Array)(arr); - } - throw 0; - } -}, { - '$data.String': function(value){ - return $data.Blob.toString(value); - }, - '$data.Array': function(value){ - return $data.Blob.toArray(value); - } -}); -(function ($data) { - - function Edm_Boolean() { }; - $data.Container.registerType('Edm.Boolean', Edm_Boolean); - $data.Container.mapType(Edm_Boolean, $data.Boolean); - - function Edm_Binary() { }; - $data.Container.registerType('Edm.Binary', Edm_Binary); - $data.Container.mapType(Edm_Binary, $data.Blob); - - function Edm_DateTime() { }; - $data.Container.registerType('Edm.DateTime', Edm_DateTime); - $data.Container.mapType(Edm_DateTime, $data.Date); - - function Edm_DateTimeOffset() { }; - $data.Container.registerType('Edm.DateTimeOffset', Edm_DateTimeOffset); - $data.Container.mapType(Edm_DateTimeOffset, $data.DateTimeOffset); - - function Edm_Time() { }; - $data.Container.registerType('Edm.Time', Edm_Time); - $data.Container.mapType(Edm_Time, $data.Time); - - function Edm_Decimal() { }; - $data.Container.registerType('Edm.Decimal', Edm_Decimal); - $data.Container.mapType(Edm_Decimal, $data.Decimal); - - function Edm_Float() { }; - $data.Container.registerType('Edm.Float', Edm_Float); - $data.Container.mapType(Edm_Float, $data.Float); - - function Edm_Single() { }; - $data.Container.registerType('Edm.Single', Edm_Single); - $data.Container.mapType(Edm_Single, $data.Float); - - function Edm_Double() { }; - $data.Container.registerType('Edm.Double', Edm_Double); - $data.Container.mapType(Edm_Double, $data.Number); - - function Edm_Guid() { }; - $data.Container.registerType('Edm.Guid', Edm_Guid); - $data.Container.mapType(Edm_Guid, $data.Guid); - - function Edm_Int16() { }; - $data.Container.registerType('Edm.Int16', Edm_Int16); - $data.Container.mapType(Edm_Int16, $data.Int16); - - function Edm_Int32() { }; - $data.Container.registerType('Edm.Int32', Edm_Int32); - $data.Container.mapType(Edm_Int32, $data.Integer); - - function Edm_Int64() { }; - $data.Container.registerType('Edm.Int64', Edm_Int64); - $data.Container.mapType(Edm_Int64, $data.Int64); - - function Edm_Byte() { }; - $data.Container.registerType('Edm.Byte', Edm_Byte); - $data.Container.mapType(Edm_Byte, $data.Byte); - - function Edm_SByte() { }; - $data.Container.registerType('Edm.SByte', Edm_SByte); - $data.Container.mapType(Edm_SByte, $data.SByte); - - function Edm_String() { }; - $data.Container.registerType('Edm.String', Edm_String); - $data.Container.mapType(Edm_String, $data.String); - - function Edm_GeographyPoint() { }; - $data.Container.registerType('Edm.GeographyPoint', Edm_GeographyPoint); - $data.Container.mapType(Edm_GeographyPoint, $data.GeographyPoint); - - function Edm_GeographyLineString() { }; - $data.Container.registerType('Edm.GeographyLineString', Edm_GeographyLineString); - $data.Container.mapType(Edm_GeographyLineString, $data.GeographyLineString); - - function Edm_GeographyPolygon() { }; - $data.Container.registerType('Edm.GeographyPolygon', Edm_GeographyPolygon); - $data.Container.mapType(Edm_GeographyPolygon, $data.GeographyPolygon); - - function Edm_GeographyMultiPoint() { }; - $data.Container.registerType('Edm.GeographyMultiPoint', Edm_GeographyMultiPoint); - $data.Container.mapType(Edm_GeographyMultiPoint, $data.GeographyMultiPoint); - - function Edm_GeographyMultiLineString() { }; - $data.Container.registerType('Edm.GeographyMultiLineString', Edm_GeographyMultiLineString); - $data.Container.mapType(Edm_GeographyMultiLineString, $data.GeographyMultiLineString); - - function Edm_GeographyMultiPolygon() { }; - $data.Container.registerType('Edm.GeographyMultiPolygon', Edm_GeographyMultiPolygon); - $data.Container.mapType(Edm_GeographyMultiPolygon, $data.GeographyMultiPolygon); - - function Edm_GeographyCollection() { }; - $data.Container.registerType('Edm.GeographyCollection', Edm_GeographyCollection); - $data.Container.mapType(Edm_GeographyCollection, $data.GeographyCollection); - - function Edm_GeometryPoint() { }; - $data.Container.registerType('Edm.GeometryPoint', Edm_GeometryPoint); - $data.Container.mapType(Edm_GeometryPoint, $data.GeometryPoint); - - function Edm_GeometryLineString() { }; - $data.Container.registerType('Edm.GeometryLineString', Edm_GeometryLineString); - $data.Container.mapType(Edm_GeometryLineString, $data.GeometryLineString); - - function Edm_GeometryPolygon() { }; - $data.Container.registerType('Edm.GeometryPolygon', Edm_GeometryPolygon); - $data.Container.mapType(Edm_GeometryPolygon, $data.GeometryPolygon); - - function Edm_GeometryMultiPoint() { }; - $data.Container.registerType('Edm.GeometryMultiPoint', Edm_GeometryMultiPoint); - $data.Container.mapType(Edm_GeometryMultiPoint, $data.GeometryMultiPoint); - - function Edm_GeometryMultiLineString() { }; - $data.Container.registerType('Edm.GeometryMultiLineString', Edm_GeometryMultiLineString); - $data.Container.mapType(Edm_GeometryMultiLineString, $data.GeometryMultiLineString); - - function Edm_GeometryMultiPolygon() { }; - $data.Container.registerType('Edm.GeometryMultiPolygon', Edm_GeometryMultiPolygon); - $data.Container.mapType(Edm_GeometryMultiPolygon, $data.GeometryMultiPolygon); - - function Edm_GeometryCollection() { }; - $data.Container.registerType('Edm.GeometryCollection', Edm_GeometryCollection); - $data.Container.mapType(Edm_GeometryCollection, $data.GeometryCollection); - - $data.oDataEdmMapping = { - '$data.Byte': 'Edm.Byte', - '$data.SByte': 'Edm.SByte', - '$data.Decimal': 'Edm.Decimal', - '$data.Float': 'Edm.Float', - '$data.Int16': 'Edm.Int16', - '$data.Int64': 'Edm.Int64', - '$data.DateTimeOffset': 'Edm.DateTimeOffset', - '$data.Time': 'Edm.Time', - '$data.Boolean': 'Edm.Boolean', - '$data.Blob': 'Edm.Binary', - '$data.Date': 'Edm.DateTime', - '$data.Number': 'Edm.Double', - '$data.Integer': 'Edm.Int32', - '$data.Int32': 'Edm.Int32', - '$data.String': 'Edm.String', - '$data.ObjectID': 'Edm.String', - '$data.GeographyPoint': 'Edm.GeographyPoint', - '$data.GeographyLineString': 'Edm.GeographyLineString', - '$data.GeographyPolygon': 'Edm.GeographyPolygon', - '$data.GeographyMultiPoint': 'Edm.GeographyMultiPoint', - '$data.GeographyMultiLineString': 'Edm.GeographyMultiLineString', - '$data.GeographyMultiPolygon': 'Edm.GeographyMultiPolygon', - '$data.GeographyCollection': 'Edm.GeographyCollection', - '$data.GeometryPoint': 'Edm.GeometryPoint', - '$data.GeometryLineString': 'Edm.GeometryLineString', - '$data.GeometryPolygon': 'Edm.GeometryPolygon', - '$data.GeometryMultiPoint': 'Edm.GeometryMultiPoint', - '$data.GeometryMultiLineString': 'Edm.GeometryMultiLineString', - '$data.GeometryMultiPolygon': 'Edm.GeometryMultiPolygon', - '$data.GeometryCollection': 'Edm.GeometryCollection', - '$data.Guid': 'Edm.Guid' - }; - -})($data); -$data.Container.registerConverter('$data.Boolean', { - '$data.String': function(value){ - if (value.toLowerCase() == 'true') return true; - if (value.toLowerCase() == 'false') return false; - - return !!value; - }, - 'default': function(value){ - return !!value; - } -}); - -$data.Container.registerConverter('$data.Integer', { - 'default': function (value) { - if (value === Number.POSITIVE_INFINITY || - value === Number.NEGATIVE_INFINITY || - value === Number.MAX_VALUE || - value === Number.MIN_VALUE) { - return value; - } - - var r = parseInt(+value, 10); - if (isNaN(r)) throw 0; - return r; - } -}); - -$data.Container.registerConverter('$data.Int32', { - 'default': function (value) { - return value | 0; - } -}); - -$data.Container.registerConverter('$data.Number', { - 'default': function(value){ - var r = +value; - if (isNaN(r)) throw 0; - return r; - } -}); - -$data.Container.registerConverter('$data.Byte', { - 'default': function(value){ - return (value | 0) & 0xff; - } -}); - -$data.Container.registerConverter('$data.Date', { - 'default': function(value){ - var d = new Date(value); - if (isNaN(d)) throw 0; - return d; - } -}); - -$data.Container.registerConverter('$data.DateTimeOffset', { - '$data.Date': function(value){ - return value; - }, - 'default': function(value){ - var d = new Date(value); - if (isNaN(d)) throw 0; - return d; - } -}); -(function () { - function parseFromString(value) { - var regex = /^([0-9]|0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]|[0-9])(:([0-5][0-9]|[0-9])(\.(\d+))?)?$/; - - var matches = regex.exec(value) - if (!matches) throw 0; - var time = ''; - time += ('00' + matches[1]).slice(-2); - time += ':' + ('00' + matches[2]).slice(-2); - if (matches[4]) { - time += ':' + ('00' + matches[4]).slice(-2); - } else { - time += ':00'; - } - if (matches[6]) - time += '.' + (matches[6] + '000').slice(0, 3); - - return time; - } - - $data.Container.registerConverter('$data.Time', { - '$data.String': parseFromString, - '$data.Number': function tt(value) { - var metrics = [1000, 60, 60]; - var result = [0, 0, 0, value | 0]; - - for (var i = 0; i < metrics.length; i++) { - result[metrics.length - (i + 1)] = (result[metrics.length - i] / metrics[i]) | 0; - result[metrics.length - i] -= result[metrics.length - (i + 1)] * metrics[i]; - } - - var time = ''; - for (var i = 0; i < result.length; i++) { - if (i < result.length - 1) { - time += ('00' + result[i]).slice(-2); - if (i < result.length - 2) time += ':'; - } else { - time += '.' + ('000' + result[i]).slice(-3); - } - } - - return parseFromString(time); - }, - '$data.Date': function (value) { - var val = value.getHours() + ':' + value.getMinutes() + ':' + value.getSeconds(); - var ms = value.getMilliseconds() - if (ms) { - val += '.' + ms; - } - - return parseFromString(val); - } - }); -})(); - -$data.Container.registerConverter('$data.Decimal', { - '$data.Boolean': function(value){ - return value ? '1' : '0'; - }, - '$data.Number': function(value){ - return value.toString(); - }, - '$data.String': function(value){ - if (!/^\-?([0-9]+(\.[0-9]+)?|Infinity)$/.test(value)) throw 0; - return value; - }, - '$data.Date': function(value){ - var r = value.valueOf(); - if (isNaN(r)) throw 0; - return r.toString(); - } -}); - -$data.packIEEE754 = function(v, ebits, fbits){ - var bias = (1 << (ebits - 1)) - 1, s, e, f, ln, i, bits, str, bytes; - - // Compute sign, exponent, fraction - if (v !== v){ - // NaN - // http://dev.w3.org/2006/webapi/WebIDL/#es-type-mapping - e = (1 << bias) - 1; f = Math.pow(2, fbits - 1); s = 0; - }else if (v === Infinity || v === -Infinity){ - e = (1 << bias) - 1; f = 0; s = (v < 0) ? 1 : 0; - }else if (v === 0){ - e = 0; f = 0; s = (1 / v === -Infinity) ? 1 : 0; - }else{ - s = v < 0; - v = Math.abs(v); - - if (v >= Math.pow(2, 1 - bias)){ - // Normalized - ln = Math.min(Math.floor(Math.log(v) / Math.LN2), bias); - e = ln + bias; - f = Math.round(v * Math.pow(2, fbits - ln) - Math.pow(2, fbits)); - }else{ - // Denormalized - e = 0; - f = Math.round(v / Math.pow(2, 1 - bias - fbits)); - } - } - - // Pack sign, exponent, fraction - bits = []; - for (i = fbits; i; i -= 1) { bits.push(f % 2 ? 1 : 0); f = Math.floor(f / 2); } - for (i = ebits; i; i -= 1) { bits.push(e % 2 ? 1 : 0); e = Math.floor(e / 2); } - bits.push(s ? 1 : 0); - bits.reverse(); - str = bits.join(''); - - // Bits to bytes - bytes = []; - while (str.length){ - bytes.push(parseInt(str.substring(0, 8), 2)); - str = str.substring(8); - } - - return bytes; -}; - -$data.unpackIEEE754 = function(bytes, ebits, fbits){ - // Bytes to bits - var bits = [], i, j, b, str, bias, s, e, f; - - for (i = bytes.length; i; i -= 1){ - b = bytes[i - 1]; - for (j = 8; j; j -= 1){ - bits.push(b % 2 ? 1 : 0); b = b >> 1; - } - } - bits.reverse(); - str = bits.join(''); - - // Unpack sign, exponent, fraction - bias = (1 << (ebits - 1)) - 1; - s = parseInt(str.substring(0, 1), 2) ? -1 : 1; - e = parseInt(str.substring(1, 1 + ebits), 2); - f = parseInt(str.substring(1 + ebits), 2); - - // Produce number - if (e === (1 << ebits) - 1){ - return f !== 0 ? NaN : s * Infinity; - }else if (e > 0){ - // Normalized - return s * Math.pow(2, e - bias) * (1 + f / Math.pow(2, fbits)); - }else if (f !== 0){ - // Denormalized - return s * Math.pow(2, -(bias - 1)) * (f / Math.pow(2, fbits)); - }else{ - return s < 0 ? -0 : 0; - } -}; - -$data.IEEE754 = function(v, e, f){ - return $data.unpackIEEE754($data.packIEEE754(v, e, f), e, f); -}; - -$data.Container.registerConverter('$data.Float', { - 'default': function(value){ - var r = +value; - if (isNaN(r)) throw 0; - return $data.IEEE754(r, 8, 23); - } -}); - -$data.Container.registerConverter('$data.Int16', { - 'default': function(value){ - var r = (value | 0) & 0xffff; - if (r >= 0x8000) return r - 0x10000; - return r; - } -}); - -$data.Container.registerConverter('$data.Int64', { - '$data.Boolean': function(value){ - return value ? '1' : '0'; - }, - '$data.Number': function(value){ - var r = value.toString(); - if (r.indexOf('.') > 0) return r.split('.')[0]; - if (r.indexOf('.') == 0) throw 0; - return r; - }, - '$data.String': function(value){ - if (!/^\-?([0-9]+(\.[0-9]+)?|Infinity)$/.test(value)) throw 0; - if (value.indexOf('.') > 0) return value.split('.')[0]; - if (value.indexOf('.') == 0) throw 0; - return value; - }, - '$data.Date': function(value){ - var r = value.valueOf(); - if (isNaN(r)) throw 0; - return r.toString(); - } -}); - -$data.Container.registerConverter('$data.SByte', { - 'default': function(value){ - var r = (value | 0) & 0xff; - if (r >= 0x80) return r - 0x100; - return r; - } -}); - -$data.Container.registerConverter('$data.String', { - '$data.Date': function(value){ - return value.toISOString(); - }, - '$data.ObjectID': function(value){ - return btoa(value.toString()); - }, - 'default': function(value){ - if (typeof value === 'object') return JSON.stringify(value); - return value.toString(); - } -}); - -$data.Container.registerConverter('$data.Object', { - '$data.String': function(value){ - return JSON.parse(value); - }, - '$data.Function': function(){ - throw 0; - } -}); - -$data.Container.registerConverter('$data.Array', { - '$data.String': function(value){ - var r = JSON.parse(value); - if (!Array.isArray(r)) throw 0; - return r; - } -}); - -$data.Container.registerConverter('$data.ObjectID', { - '$data.ObjectID': function(value){ - try{ - return btoa(value.toString()); - }catch(e){ - return value; - } - }, - '$data.String': function(id){ - return id; - } -}); - -$data.Container.proxyConverter = function(v){ return v; }; -$data.Container.defaultConverter = function(type){ return function(v){ return $data.Container.convertTo(v, type); }; }; -$data.StringFunctions = { - startsWith: function () { - var self, str; - if (arguments.length == 2) { - self = arguments[0]; - str = arguments[1]; - } else if (arguments.length == 1 && typeof this === 'string') { - self = this; - str = arguments[0]; - } else if (this instanceof String) { - self = this.valueOf(); - str = arguments[0]; - } else - return false; - - if (typeof self !== 'string') return false; - return self.indexOf(str) === 0; - }, - endsWith: function () { - var self, str; - if (arguments.length == 2) { - self = arguments[0]; - str = arguments[1]; - } else if (arguments.length == 1 && typeof this === 'string') { - self = this; - str = arguments[0]; - } else if (this instanceof String) { - self = this.valueOf(); - str = arguments[0]; - } else - return false; - - if (typeof self !== 'string') return false; - return self.slice(-str.length) === str; - }, - contains: function () { - var self, str; - if (arguments.length == 2) { - self = arguments[0]; - str = arguments[1]; - } else if (arguments.length == 1 && typeof this === 'string') { - self = this; - str = arguments[0]; - } else if (this instanceof String) { - self = this.valueOf(); - str = arguments[0]; - } else - return false; - - if (typeof self !== 'string') return false; - return self.indexOf(str) >= 0; - } -}; -//TODO: Finish refactoring ExpressionNode.js - -$data.Class.define("$data.Expressions.ExpressionType", null, null, {}, { - Constant: "constant", // { type:LITERAL, executable:true, valueType:, value: } - Variable: "variable", // { type:VARIABLE, executable:true, name: } - MemberAccess: "memberAccess", // { type:MEMBERACCESS, executable:true, expression:, member: } - Call: "call", - - /* binary operators */ - Equal: "equal", - NotEqual: "notEqual", - EqualTyped: "equalTyped", - NotEqualTyped: "notEqualTyped", - GreaterThen: "greaterThan", - LessThen: "lessThan", - GreaterThenOrEqual: "greaterThanOrEqual", - LessThenOrEqual: "lessThenOrEqual", - Or: "or", - OrBitwise: "orBitwise", - And: "and", - AndBitwise: "andBitwise", - - - In: "in", - - Add: "add", - Divide: "divide", - Multiply: "multiply", - Subtract: "subtract", - Modulo: "modulo", - ArrayIndex: "arrayIndex", - - /* unary operators */ - New: "new", - Positive: "positive", - Negative: "negative", - Increment: "increment", - Decrement: "decrement", - Not: "not", - - - This: "this", - LambdaParameterReference: "lambdaParameterReference", - LambdaParameter: "lambdaParameter", - Parameter: "parameter", - - ArrayLiteral: "arrayLiteral", - ObjectLiteral: "objectLiteral", - ObjectField: "objectField", - Function: "Function", - Unknown: "UNKNOWN", - - EntitySet: "EntitySet", - ServiceOperation: "ServiceOperation", - EntityField: "EntityField", - EntityContext: "EntityContext", - Entity: "Entity", - Filter: "Filter", - First: "First", - Count: "Count", - InlineCount: "InlineCount", - Single: "Single", - Find: "Find", - Some: "Some", - Every: "Every", - ToArray: "ToArray", - BatchDelete: "BatchDelete", - ForEach: "ForEach", - Projection: "Projection", - EntityMember: "EntityMember", - EntityFieldOperation: "EntityFieldOperation", - FrameOperation: "FrameOperation", - EntityFunctionOperation: "EntityFunctionOperation", - ContextFunctionOperation: "ContextFunctionOperation", - EntityBinary: "EntityBinary", - Code: "Code", - ParametricQuery: "ParametricQuery", - MemberInfo: "MemberInfo", - QueryParameter: "QueryParameter", - ComplexEntityField: "ComplexEntityField", - - Take: "Take", - Skip: "Skip", - OrderBy: "OrderBy", - OrderByDescending: "OrderByDescending", - Include: "Include", - - IndexedPhysicalAnd:"IndexedDBPhysicalAndFilterExpression", - IndexedLogicalAnd:"IndexedDBLogicalAndFilterExpression", - IndexedLogicalOr: "IndexedDBLogicalOrFilterExpression", - IndexedLogicalIn: "IndexedDBLogicalInFilterExpression" -}); - -$data.BinaryOperator = function () { - /// - /// - /// -} - -$data.binaryOperators = [ - { operator: "==", expressionType: $data.Expressions.ExpressionType.Equal, type: "boolean", implementation: function (a, b) { return a == b; } }, - { operator: "===", expressionType: $data.Expressions.ExpressionType.EqualTyped, type: "boolean", implementation: function (a, b) { return a === b; } }, - { operator: "!=", expressionType: $data.Expressions.ExpressionType.NotEqual, type: "boolean", implementation: function (a, b) { return a != b; } }, - { operator: "!==", expressionType: $data.Expressions.ExpressionType.NotEqualTyped, type: "boolean", implementation: function (a, b) { return a !== b; } }, - { operator: ">", expressionType: $data.Expressions.ExpressionType.GreaterThen, type: "boolean", implementation: function (a, b) { return a > b; } }, - { operator: ">=", expressionType: $data.Expressions.ExpressionType.GreaterThenOrEqual, type: "boolean", implementation: function (a, b) { return a >= b; } }, - { operator: "<=", expressionType: $data.Expressions.ExpressionType.LessThenOrEqual, type: "boolean", implementation: function (a, b) { return a <= b; } }, - { operator: "<", expressionType: $data.Expressions.ExpressionType.LessThen, type: "boolean", implementation: function (a, b) { return a < b; } }, - { operator: "&&", expressionType: $data.Expressions.ExpressionType.And, type: "boolean", implementation: function (a, b) { return a && b; } }, - { operator: "||", expressionType: $data.Expressions.ExpressionType.Or, type: "boolean", implementation: function (a, b) { return a || b; } }, - { operator: "&", expressionType: $data.Expressions.ExpressionType.AndBitwise, type: "number", implementation: function (a, b) { return a & b; } }, - { operator: "|", expressionType: $data.Expressions.ExpressionType.OrBitwise, type: "number", implementation: function (a, b) { return a | b; } }, - { operator: "+", expressionType: $data.Expressions.ExpressionType.Add, type: "number", implementation: function (a, b) { return a + b; } }, - { operator: "-", expressionType: $data.Expressions.ExpressionType.Subtract, type: "number", implementation: function (a, b) { return a - b; } }, - { operator: "/", expressionType: $data.Expressions.ExpressionType.Divide, type: "number", implementation: function (a, b) { return a / b; } }, - { operator: "%", expressionType: $data.Expressions.ExpressionType.Modulo, type: "number", implementation: function (a, b) { return a % b; } }, - { operator: "*", expressionType: $data.Expressions.ExpressionType.Multiply, type: "number", implementation: function (a, b) { return a * b; } }, - { operator: "[", expressionType: $data.Expressions.ExpressionType.ArrayIndex, type: "number", implementation: function (a, b) { return a[b]; } }, - { operator: "in", expressionType: $data.Expressions.ExpressionType.In, type: 'boolean', implementation: function (a, b) { return a in b; } } -]; - - -$data.binaryOperators.resolve = function (operator) { - var result = $data.binaryOperators.filter(function (item) { return item.operator == operator; }); - if (result.length > 0) - return operator; - //Guard.raise("Unknown operator: " + operator); -}; - -$data.binaryOperators.contains = function (operator) { - return $data.binaryOperators.some(function (item) { return item.operator == operator; }); -}; - -$data.binaryOperators.getOperator = function (operator) { - /// - var result = $data.binaryOperators.filter(function (item) { return item.operator == operator; }); - if (result.length < 1) - Guard.raise("Unknown operator: " + operator); - return result[0]; -}; - - -$data.unaryOperators = [ - { operator: "+", arity: "prefix", expressionType: $data.Expressions.ExpressionType.Positive, type: "number", implementation: function (operand) { return +operand; } }, - { operator: "-", arity: "prefix", expressionType: $data.Expressions.ExpressionType.Negative, type: "number", implementation: function (operand) { return -operand; } }, - { operator: "++", arity: "prefix", expressionType: $data.Expressions.ExpressionType.Increment, type: "number", implementation: function (operand) { return ++operand; } }, - { operator: "--", arity: "prefix", expressionType: $data.Expressions.ExpressionType.Decrement, type: "number", implementation: function (operand) { return --operand; } }, - { operator: "++", arity: "suffix", expressionType: $data.Expressions.ExpressionType.Increment, type: "number", implementation: function (operand) { return operand++; } }, - { operator: "!", arity: "prefix", expressionType: $data.Expressions.ExpressionType.Not, type: "boolean", implementation: function (operand) { return !operand; } }, - { operator: "--", arity: "suffix", expressionType: $data.Expressions.ExpressionType.Decrement, type: "number", implementation: function (operand) { return operand--; } } - - //{ operator: "new", expressionType : $data.Expressions.ExpressionType.New, type: "object", implementation: function(operand) { return new operand; } -]; - -$data.unaryOperators.resolve = function (operator) { - var result = $data.unaryOperators.filter(function (item) { return item.operator == operator; }); - if (result.length > 0) - return operator; - //Guard.raise("Unknown operator: " + operator); -}; - -$data.unaryOperators.contains = function (operator) { - return $data.unaryOperators.some(function (item) { return item.operator == operator; }); -}; - -$data.unaryOperators.getOperator = function (operator, arity) { - /// - var result = $data.unaryOperators.filter(function (item) { return item.operator == operator && (!arity || item.arity == arity); }); - if (result.length < 1) - Guard.raise("Unknown operator: " + operator); - return result[0]; -}; - - -$data.timeIt = function (fn, iterations) { - iterations = iterations || 1; - - console.time("!"); - for (var i = 0; i < iterations; i++) { - fn(); - } - console.timeEnd("!"); -} - -$data.Expressions.OperatorTypes = { - UNARY: "UNARY", // { type:UNARY, executable:true, operator:, operand: } - INCDEC: "INCDEC", // { type:INCDEC, executable:true, operator:, operand:, suffix: } - DECISION: "DECISION", // { type:DECISION, executable:true, expression:, left:, right: } - METHODCALL: "METHODCALL", // { type:METHODCALL, executable:true, object:, method:, args: } - NEW: "NEW", // { type:NEW, executable:true, values: [] }; - JSONASSIGN: "JSONASSIGN", // { type:JSONASSIGN, executable:true, left:, right: } - ARRAYACCESS: "ARRAYACCESS", // { type:ARRAYACCESS, executable:true, array:, index: } - UNKNOWN: "UNKNOWN" -}; - -$data.executable = true; - -function jsonify(obj) { return JSON.stringify(obj, null, "\t"); } - -$C('$data.Expressions.ExpressionNode', null, null, { - constructor: function () { - ///Provides a base class for all Expressions. - ///Represents the expression type of the node - ///For the list of expression node types refer to $data.Expressions.ExpressionType - /// - ///The result type of the expression - ///True if the expression can be evaluated to yield a result - ///this.nodeType = $data.Expressions.ExpressionType.Unknown; - ///this.type = type; - ///this.nodeType = $data.Expressions.ExpressionType.Unknown; - ///this.executable = (executable === undefined || executable === null) ? true : executable; - ///TODO - this.expressionType = this.constructor; - }, - - getJSON: function () { return jsonify(this); }, - - //TOBLOG maybe - /*expressionType: { - value: undefined, - ////OPTIMIZE - set: function (value) { - var _expressionType; - Object.defineProperty(this, "expressionType", { - set: function (value) { - if (typeof value === 'string') { - value = Container.resolveType(value); - } - _expressionType = value; - }, - get: function (value) { - //IE ommits listing JSON.stringify in call chain - - if (arguments.callee.caller == jsonify || arguments.callee.caller == JSON.stringify) { - return Container.resolveName(_expressionType); - } - return _expressionType; - }, - enumerable: true - }); - - this.expressionType = value; - }, - get: function () { return undefined; }, - enumerable: true - },*/ - expressionType: { - set: function (value) { - if (typeof value === 'string') { - value = Container.resolveType(value); - } - this._expressionType = value; - }, - get: function (value) { - //IE ommits listing JSON.stringify in call chain - - if (arguments.callee.caller == jsonify || arguments.callee.caller == JSON.stringify) { - return Container.resolveName(this._expressionType); - } - return this._expressionType; - }, - enumerable: true - }, - ///toString: function () { }, - nodeType: { value: $data.Expressions.ExpressionType.Unknown, writable: false }, - - type: {}, - - isTerminated: { value: false }, - - toString: function () { - return this.value; - } -}, null); - - -$C('$data.Expressions.UnaryExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (operand, operator, nodeType, resolution) { - /// - /// Represents an operation with only one operand and an operator - /// - /// - /// - /// - /// - this.operand = operand; - this.operator = operator; - this.nodeType = nodeType; - this.resolution = resolution; - }, - - operator: { value: undefined, writable: true }, - operand: { value: undefined, writable: true }, - nodeType: { value: undefined, writable: true } -}); -$C('$data.Expressions.ArrayLiteralExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (items) { - /// - /// - /// - this.items = items || []; - }, - nodeType: { value: $data.Expressions.ExpressionType.ArrayLiteral, writable: true }, - - items: { value: undefined, dataType: Array, elementType: $data.Expressions.ExpressionNode }, - - toString: function (debug) { - //var result; - //result = debug ? this.type + " " : ""; - //result = result + this.name; - ///Represents a call to an object or global method - ///The expression for object that has the method - ///The member descriptor - this.expression = expression; - this.member = member; - this.args = args; - }, - - nodeType: { - value: $data.Expressions.ExpressionType.Call - }, - - expression: { - value: undefined, - dataType: $data.Expressions.ExpressionNode, - writable: true - }, - - member: { - value: undefined, - dataType: $data.MemberDefinition, - writable: true - }, - - type: { - value: undefined, - writable: true - }, - - implementation: { - get: function () { - return function(thisObj, method, args) { - if (typeof method !== 'function') { - method = thisObj[method]; - } - Guard.requireType("method", method, Function); - return method.apply(thisObj, args); - }; - }, - set: function (value) { Guard.raise("Property can not be set"); } - }, - - toString: function (debug) { - return this.object.toString() + "." + this.member.toString() + "(" + ")"; - } - -}); -$C('$data.Expressions.CodeParser', null, null, { - - constructor: function (scopeContext) { - /// - /// - /// - /// - /// - this.scopeContext = scopeContext; - this.lambdaParams = []; - }, - - log: function(logInfo) { - if (this.scopeContext) - this.scopeContext.log(logInfo); - }, - - parseExpression: function (code, resolver) { - /// - ///Parses the provided code and returns a parser result with parser information - ///The JavaScript code to parse ex: "function (a,b,c) { return a + b /c }" - ///The ParameterResolver class that resolves vaiable and parameteres references - /// - /// - if (typeof code === 'object') { code = ''; } - var result = { - success: true, - errorMessage: '', - errorDetails: '' - }; - /// - - //console.log(code.toString()); - if ($data.Acorn){ - //console.log('using acorn.js'); - return { success: true, expression: this.ParserBuild($data.Acorn.parse('(' + code.toString() + ')').body[0]), errors: [] }; - }else if ($data.Esprima){ - //console.log('using esprima.js'); - return { success: true, expression: this.ParserBuild($data.Esprima.parse('(' + code.toString() + ')').body[0]), errors: [] }; - }else{ - //console.log('using JayLint'); - var AST = $data.ASTParser.parseCode(code); - this.log({ event: "AST", data: AST }); - if (!AST.success) { - return { - success: false, - error: "ASTParser error", - errorMessage: (AST.errors) ? JSON.stringify(AST.errors) : "could not get code" - }; - } - var b = this.Build2(AST.tree.first[0]); - result = { success: true, expression: b, errors: AST.errors }; - return result; - } - }, - - createExpression: function (code, resolver) { - /// - ///Parses the provided code and returns a JavaScript code expression tree - ///The JavaScript code to parse ex: "a + b /c" - ///The ParameterResolver class that resolves vaiable and parameteres references - /// - /// - /// - ///Parses the provided code and returns a JavaScript code expression tree - ///The JavaScript function to parse ex: "function (a,b,c) { return a + b /c }" - ///The ParameterResolver class that resolves vaiable and parameteres references - /// - /// - - var result = this.parseExpression(code, resolver); - if (!result.success) { - Guard.raise("ExpressionParserError: " + result.errorMessage); - } - return result.expression; - }, - - ParserBuild: function(node){ - //console.log(node); - return this['Parser' + node.type](node); - }, - - ParserExpressionStatement: function(node){ - return this.ParserBuild(node.expression); - }, - - ParserBlockStatement: function(node){ - return this.ParserBuild(node.body[0]); - }, - - ParserReturnStatement: function(node){ - return this.ParserBuild(node.argument); - }, - - ParserMemberExpression: function(node){ - return new $data.Expressions.PropertyExpression( - this.ParserBuild(node.object), - new $data.Expressions.ConstantExpression(node.property.name || node.property.value, typeof (node.property.name || node.property.value)) - ); - }, - - ParserIdentifier: function(node){ - return this.ParserParameter(node, - this.lambdaParams.indexOf(node.name) > -1 - ? $data.Expressions.ExpressionType.LambdaParameterReference - : $data.Expressions.ExpressionType.Parameter - ); - }, - - ParserObjectExpression: function(node){ - var props = new Array(node.properties.length); - for (var i = 0; i < node.properties.length; i++){ - props[i] = this.ParserProperty(node.properties[i]); - } - - return new $data.Expressions.ObjectLiteralExpression(props); - }, - - ParserArrayExpression: function(node){ - var items = new Array(node.elements.length); - for (var i = 0; i < node.elements.length; i++){ - items[i] = this.ParserBuild(node.elements[i]); - } - - return new $data.Expressions.ArrayLiteralExpression(items); - }, - - ParserProperty: function(node){ - return new $data.Expressions.ObjectFieldExpression(node.key.name, this.ParserBuild(node.value)); - }, - - ParserFunctionExpression: function(node){ - var params = new Array(node.params.length); - for (var i = 0; i < node.params.length; i++){ - this.lambdaParams.push(node.params[i].name); - params[i] = this.ParserParameter(node.params[i], $data.Expressions.ExpressionType.LambdaParameter); - params[i].owningFunction = result; - } - var result = new $data.Expressions.FunctionExpression(node.id ? node.id.name : node.id, params, this.ParserBuild(node.body)); - - return result; - }, - - ParserParameter: function(node, nodeType){ - var result = new $data.Expressions.ParameterExpression(node.name, null, nodeType); - if (nodeType == $data.Expressions.ExpressionType.LambdaParameterReference){ - result.paramIndex = this.lambdaParams.indexOf(node.name); - } - - return result; - }, - - ParserLogicalExpression: function(node){ - return this.ParserBinaryExpression(node); - }, - - ParserOperators: { - value: { - "==": { expressionType: $data.Expressions.ExpressionType.Equal, type: "boolean", implementation: function (a, b) { return a == b; } }, - "===": { expressionType: $data.Expressions.ExpressionType.EqualTyped, type: "boolean", implementation: function (a, b) { return a === b; } }, - "!=": { expressionType: $data.Expressions.ExpressionType.NotEqual, type: "boolean", implementation: function (a, b) { return a != b; } }, - "!==": { expressionType: $data.Expressions.ExpressionType.NotEqualTyped, type: "boolean", implementation: function (a, b) { return a !== b; } }, - ">": { expressionType: $data.Expressions.ExpressionType.GreaterThen, type: "boolean", implementation: function (a, b) { return a > b; } }, - ">=": { expressionType: $data.Expressions.ExpressionType.GreaterThenOrEqual, type: "boolean", implementation: function (a, b) { return a >= b; } }, - "<=": { expressionType: $data.Expressions.ExpressionType.LessThenOrEqual, type: "boolean", implementation: function (a, b) { return a <= b; } }, - "<": { expressionType: $data.Expressions.ExpressionType.LessThen, type: "boolean", implementation: function (a, b) { return a < b; } }, - "&&": { expressionType: $data.Expressions.ExpressionType.And, type: "boolean", implementation: function (a, b) { return a && b; } }, - "||": { expressionType: $data.Expressions.ExpressionType.Or, type: "boolean", implementation: function (a, b) { return a || b; } }, - "&": { expressionType: $data.Expressions.ExpressionType.AndBitwise, type: "number", implementation: function (a, b) { return a & b; } }, - "|": { expressionType: $data.Expressions.ExpressionType.OrBitwise, type: "number", implementation: function (a, b) { return a | b; } }, - "+": { expressionType: $data.Expressions.ExpressionType.Add, type: "number", implementation: function (a, b) { return a + b; } }, - "-": { expressionType: $data.Expressions.ExpressionType.Subtract, type: "number", implementation: function (a, b) { return a - b; } }, - "/": { expressionType: $data.Expressions.ExpressionType.Divide, type: "number", implementation: function (a, b) { return a / b; } }, - "%": { expressionType: $data.Expressions.ExpressionType.Modulo, type: "number", implementation: function (a, b) { return a % b; } }, - "*": { expressionType: $data.Expressions.ExpressionType.Multiply, type: "number", implementation: function (a, b) { return a * b; } }, - "[": { expressionType: $data.Expressions.ExpressionType.ArrayIndex, type: "number", implementation: function (a, b) { return a[b]; } }, - "in": { expressionType: $data.Expressions.ExpressionType.In, type: 'boolean', implementation: function (a, b) { return a in b; } } - } - }, - - ParserUnaryOperators: { - value: { - "+": { arity: "prefix", expressionType: $data.Expressions.ExpressionType.Positive, type: "number", implementation: function (operand) { return +operand; } }, - "-": { arity: "prefix", expressionType: $data.Expressions.ExpressionType.Negative, type: "number", implementation: function (operand) { return -operand; } }, - "++true": { arity: "prefix", expressionType: $data.Expressions.ExpressionType.Increment, type: "number", implementation: function (operand) { return ++operand; } }, - "--true": { arity: "prefix", expressionType: $data.Expressions.ExpressionType.Decrement, type: "number", implementation: function (operand) { return --operand; } }, - "++false": { arity: "suffix", expressionType: $data.Expressions.ExpressionType.Increment, type: "number", implementation: function (operand) { return operand++; } }, - "!": { arity: "prefix", expressionType: $data.Expressions.ExpressionType.Not, type: "boolean", implementation: function (operand) { return !operand; } }, - "--false": { arity: "suffix", expressionType: $data.Expressions.ExpressionType.Decrement, type: "number", implementation: function (operand) { return operand--; } } - } - }, - - ParserUnaryExpression: function(node){ - return new $data.Expressions.UnaryExpression(this.ParserBuild(node.argument), this.ParserUnaryOperators[node.operator], this.ParserUnaryOperators[node.operator].expressionType); - }, - - ParserUpdateExpression: function(node){ - return new $data.Expressions.UnaryExpression(this.ParserBuild(node.argument), this.ParserUnaryOperators[node.operator + node.prefix], this.ParserUnaryOperators[node.operator + node.prefix].nodeType); - }, - - ParserBinaryExpression: function(node){ - return new $data.Expressions.SimpleBinaryExpression( - this.ParserBuild(node.left), - this.ParserBuild(node.right), - this.ParserOperators[node.operator].expressionType, - node.operator, - this.ParserOperators[node.operator].type - ); - }, - - ParserThisExpression: function(node){ - return new $data.Expressions.ThisExpression(); - }, - - ParserLiteral: function(node){ - return new $data.Expressions.ConstantExpression(node.value, typeof node.value); - }, - - ParserCallExpression: function(node){ - var method = this.ParserBuild(node.callee); - var args = new Array(node.arguments.length); - for (var i = 0; i < node.arguments.length; i++){ - args[i] = this.ParserBuild(node.arguments[i]); - } - - var member; - var expression; - switch (true){ - case method instanceof $data.Expressions.PropertyExpression: - expression = method.expression; - member = method.member; - break; - case method instanceof $data.Expressions.ParameterExpression: - expression = new $data.Expressions.ConstantExpression(null, typeof null); - member = method; - break; - } - - return new $data.Expressions.CallExpression(expression, member, args); - }/*, - - Build2: function (node) { - /// - /// - var n; - switch (node.arity) { - case "number": - case "string": - n = this.BuildConstant(node); - break; - case "prefix": - switch (node.value) { - case "{": - n = this.BuildObjectLiteral(node); - break; - case "[": - n = this.BuildArrayLiteral(node); - break; - case $data.unaryOperators.resolve(node.value): - n = this.BuildUnary(node); - break; - //TODO: default case - } - break; - case "suffix": - switch (node.value) { - case $data.unaryOperators.resolve(node.value): - n = this.BuildUnary(node); - break; - default: - Guard.raise("Unknown suffix: " + node.value); - } - break; - case "infix": - switch (node.value) { - case "[": - n = this.BuildArray(node); - break; - case $data.binaryOperators.resolve(node.value): - n = this.BuildSimpleBinary(node); - break; - case "function": - Guard.raise("Unexpected function arity"); - case "(": - n = this.BuildCall(node); - break; - case ".": - n = this.BuildProperty(node); - break; - default: - debugger; - //TODO: remove debugger, throw exception or break - } - break; - case "statement": - switch (node.value) { - case "function": - n = this.BuildFunction(node); - //TODO: consider adding break - } - break; - default: - switch (node.value) { - case "function": - n = this.BuildFunction(node); - break; - case "true": - case "false": - case "null": - n = this.BuildConstant(node); - break; - case "this": - n = this.BuildThis(node); - break; - default: - n = this.BuildParameter(node); - break; - } - } - return n; - }, - - BuildThis: function (node) { - var result = Container.createThisExpression(); - return result; - }, - - BuildConstant: function (node) { - /// - var value = node.value; - var type = node.type; - if (node.reserved === true) { - switch (node.value) { - case "true": value = true; type = typeof true; break; - case "false": value = false; type = typeof false; break; - case "null": value = null; type = typeof null; break; - //TODO: missing default case - } - } - var result = new $data.Expressions.ConstantExpression(value, type); - return result; - }, - - BuildFunctionParameter: function (node) { - - }, - - BuildArray: function (node) { - switch (node.second.type) { - case "string": - return this.BuildProperty(node); - case "number": - default: - return this.BuildSimpleBinary(node); - } - }, - - BuildParameter: function (node) { - /// - /// - var paramName = node.value; - //TODO - //var paramType = this.resolver.resolveParameterType(node); - var nodeType = node.funct ? $data.Expressions.ExpressionType.LambdaParameter : - this.lambdaParams.indexOf(node.value) > -1 ? - $data.Expressions.ExpressionType.LambdaParameterReference : $data.Expressions.ExpressionType.Parameter; - var result = new $data.Expressions.ParameterExpression(node.value, null, nodeType); - - if (nodeType == $data.Expressions.ExpressionType.LambdaParameterReference) { - result.paramIndex = this.lambdaParams.indexOf(node.value); - } - - return result; - }, - - BuildArrayLiteral: function(node) { - var self = this; - var items = node.first.map(function (item) { return self.Build2(item); }); - var result = new $data.Expressions.ArrayLiteralExpression(items); - return result; - }, - - BuildObjectLiteral: function (node) { - var self = this; - var fields = node.first.map(function (item) { - var eItem = self.Build2(item.first); - var result = new $data.Expressions.ObjectFieldExpression(item.value, eItem); - return result; - }); - var result = new $data.Expressions.ObjectLiteralExpression(fields); - return result; - }, - - BuildFunction: function (node) { - /// - /// - var self = this; - var paramStack = []; - var params = node.first && node.first.map(function (paramNode) { - //paramStack.push(paramNode.value); - this.lambdaParams.push(paramNode.value); - return self.BuildParameter(paramNode); - }, this); - params = params || []; - - //skipping return for convenience - //Possible we should raise an error as predicates and selectors can - //not be code blocks just expressions - - var hasReturn = node.block.length == 0 ? false : - node.block[0].value === "return" ? true : false; - var body = (node.block.length > 0) ? this.Build2(hasReturn ? node.block[0].first : node.block[0]) : null; - - paramStack.forEach(function () { this.lambdaParams.pop(); }, this); - - var result = new $data.Expressions.FunctionExpression(node.value, params, body); - params.forEach(function (param) { - param.owningFunction = result; - }); - - //TODO place on prototyope - result.name = node.name; - return result; - }, - - BuildCall: function (node) { - var self = this; - var method = self.Build2(node.first); - var args = node.second.map(function (exp) { return self.Build2(exp); }); - var member; - var expression; - switch(true){ - case method instanceof $data.Expressions.PropertyExpression: - expression = method.expression; - member = method.member; - break; - case method instanceof $data.Expressions.ParameterExpression: - expression = Container.createConstantExpression(null, typeof null); - member = method; - break; - //TODO: missing default case - } - - var result = Container.createCallExpression(expression, member, args); - return result; - }, - - BuildProperty: function (node) { - ///Builds a PropertyExpression from the AST node - /// - /// - var expression = this.Build2(node.first); - //TODO - //var type = expression.type; - //var member = type.getMemberDefinition() - //TODO how to not if????? - var member; - if (node.second.identifier) { - member = new $data.Expressions.ConstantExpression(node.second.value, "string"); - } else { - member = this.Build2(node.second); - } - var result = new $data.Expressions.PropertyExpression(expression, member); - return result; - }, - - - BuildUnary: function(node) { - var operator = $data.unaryOperators.getOperator(node.value, node.arity); - var nodeType = operator.expressionType; - var operand = this.Build2(node.first); - var result = new $data.Expressions.UnaryExpression(operand, operator, nodeType); - return result; - }, - - BuildSimpleBinary: function (node) { - /// - - var operator = $data.binaryOperators.getOperator(node.value); - var nodeType = operator.expressionType; - - var left = this.Build2(node.first || node.left); - var right = this.Build2(node.second || node.right); - var result = new $data.Expressions.SimpleBinaryExpression(left, right, nodeType, node.value, operator.type); - return result; - } - - //Build: function (node, expNode) { - // var n; - // switch (node.arity) { - // case "ternary": - // if (node.value == "?") - // n = this.BuildDecision(node, expNode); - // else - // Guard.raise("Value of ternary node isn't implemented: " + node.value); - // break; - // case null: - // default: - // Guard.raise("Arity isn't implemented: " + node.arity); - // } - // return n; - //},*/ - -}); - -$C('$data.Expressions.ConstantExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (value, type, name) { - this.value = value; - //TODO - //this.type = Container.getTypeName(value); - - this.type = type; - this.name = name; - if (!Object.isNullOrUndefined(this.value)) { - this.type = Container.resolveType(this.type) - if (Container.resolveType(Container.getTypeName(this.value)) !== this.type) - this.value = Container.convertTo(value, this.type); - } - }, - nodeType: { value: $data.Expressions.ExpressionType.Constant, enumerable: true }, - type: { value: Object, writable: true }, - value: { value: undefined, writable: true }, - toString: function (debug) { - //return "[constant: " + this.value.toString() + "]"; - return this.value.toString(); - } -}); - - -$C('$data.Expressions.FunctionExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (name, parameters, body) { - /// - ///Represents a function declaration. - ///Function name - ///The list of function parameters - /// - /// - ///The list of function parameters - ///The function body - - this.parameters = parameters || []; - this.name = name; - this.body = body; - }, - - toString: function (debug) { - var paramStrings = this.parameters.map(function (p) { - return p.toString(); - }); - paramStrings = paramStrings.join(","); - var bodyString = (this.body ? this.body.toString(debug) : ''); - return "function " + this.name + "(" + paramStrings + ") { " + bodyString + "}"; - }, - nodeType: { value: $data.Expressions.ExpressionType.Function, writable: true }, - parameters: { value: undefined, dataType: Array, elementType: $data.Expressions.ParameterExpression }, - body: { value: undefined, dataType: $data.Expressions.ExpressionNode }, - type: {} -}, null); -$C('$data.Expressions.ObjectFieldExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (fieldName, expression) { - /// - /// - this.fieldName = fieldName; - this.expression = expression; - }, - nodeType: { value: $data.Expressions.ExpressionType.ObjectField, writable: true }, - - toString: function (debug) { - //var result; - //result = debug ? this.type + " " : ""; - //result = result + this.name; - var result = "unimplemented"; - return result; - } -}, null); - -$C('$data.Expressions.ObjectLiteralExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (members) { - ///Represent an object initializer literal expression Ex: { prop: value} - /// - this.members = members; - }, - nodeType: { value: $data.Expressions.ExpressionType.ObjectLiteral, writable: true }, - - toString: function (debug) { - //var result; - //result = debug ? this.type + " " : ""; - //result = result + this.name; - var result = "unimplemented"; - return result; - }, - - implementation: { - get: function () { - return function(namesAndValues) { - var result = { }; - namesAndValues.forEach(function(item) { - result[item.name] = item.value; - }); - return result; - }; - }, - set: function () { - } - } - -}, null); -$C('$data.Expressions.PagingExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (source, expression, nType) { - /// - /// - this.source = source; - this.amount = expression; - this.nodeType = nType; - }, - nodeType: { value: $data.Expressions.ExpressionType.Unknown, writable: true }, - - toString: function (debug) { - //var result; - //result = debug ? this.type + " " : ""; - //result = result + this.name; - var result = "unimplemented"; - return result; - } -}, null); -$C('$data.Expressions.ParameterExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (name, type, nodeType) { - /// - /// - //this.writePropertyValue("name", name); - //this.writePropertyValue("type", type); - this.nodeType = nodeType || $data.Expressions.ExpressionType.Parameter; - this.name = name; - this.type = type || "unknown"; - var _owningFunction; - }, - - owningFunction: { value: undefined, enumerable: false }, - nodeType: { value: $data.Expressions.ExpressionType.Parameter, writable: true }, - name: { value: undefined, dataType: String, writable: true }, - type: { value: undefined, dataType: "object", writable: true}, - toString: function (debug) { - var result; - result = debug ? this.type + " " : ""; - result = result + this.name; - return result; - } -}, null); -$C('$data.Expressions.PropertyExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (expression, member) { - ///Represents accessing a property or field of an object - ///The expression for the property owner object - ///The member descriptor - ///The expression for the property owner object - ///The member descriptor - - this.expression = expression; - this.member = member; - - this.type = member.dataType; - }, - - nodeType: { - value: $data.Expressions.ExpressionType.MemberAccess - }, - - expression: { - value: undefined, - dataType: $data.Expressions.ExpressionNode, - writable: true - }, - - implementation: { - get: function () { - return function (holder, memberName) { - if (holder[memberName] === undefined) - Guard.raise(new Exception("Parameter '" + memberName + "' not found in context", 'Property not found!')); - return holder[memberName]; - }; - }, - set: function () { - } - }, - - member: { - value: undefined, - dataType: $data.MemberDefinition, - writable: true - }, - - type: { - value: undefined, - writable: true - }, - - toString: function (debug) { - return this.expression.toString() + "." + this.member.toString(); - } - -}); - -$C('$data.Expressions.SimpleBinaryExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (left, right, nodeType, operator, type, resolution) { - ///Represents a bin operation with left and right operands and an operator/// - ///The left element of the binary operation - ///The right element of the binary operation - /// - this.left = left; - this.right = right; - this.nodeType = nodeType; - this.operator = operator; - this.type = type; - this.resolution = resolution; - }, - - implementation: { - get: function () { - return $data.binaryOperators.getOperator(this.operator).implementation; - }, - set: function () { } - - }, - //nodeType: { value: $data.Expressions.ExpressionType }, - type: { value: "number", writable: true } -}); -$C('$data.Expressions.ThisExpression', $data.Expressions.ExpressionNode, null, { - nodeType: { value: $data.Expressions.ExpressionType.This } -}); -$C('$data.Expressions.ExpressionVisitor', null, null, - { - constructor: function () { - this._deep = 0; - }, - - Visit: function (eNode, context) { - /// - /// - /// - // - - //this._deep = this._deep + 1; - if (!eNode) { - return eNode; - } - - var result = null; - - switch (eNode.expressionType) { - case $data.Expressions.ParameterExpression: - result = this.VisitParameter(eNode, context); - break; - case $data.Expressions.ConstantExpression: - result = this.VisitConstant(eNode, context); - break; - case $data.Expressions.FunctionExpression: - result = this.VisitFunction(eNode, context); - break; - case $data.Expressions.CallExpression: - result = this.VisitCall(eNode, context); - break; - case $data.Expressions.SimpleBinaryExpression: - result = this.VisitBinary(eNode, context); - break; - case $data.Expressions.PropertyExpression: - result = this.VisitProperty(eNode, context); - break; - //result = th - case $data.Expressions.ThisExpression: - result = this.VisitThis(eNode, context); - break; - case $data.Expressions.ObjectLiteralExpression: - result = this.VisitObjectLiteral(eNode, context); - break; - case $data.Expressions.ObjectFieldExpression: - result = this.VisitObjectField(eNode, context); - break; - case $data.Expressions.ArrayLiteralExpression: - result = this.VisitArrayLiteral(eNode, context); - break; - case $data.Expressions.UnaryExpression: - result = this.VisitUnary(eNode, context); - break; - case $data.Expressions.EntityContextExpression: - result = this.VisitEntityContext(eNode, context); - break; - default: - debugger; - break; - //case VARIABLE: - - // result = this.VisitVariable(eNode, context); - // break; - //case MEMBERACCESS: - // result = this.VisitMember(eNode, context); - // break; - //case BINARY: - // result = this.VisitBinary(eNode, context); - // break; - //case UNARY: - // result = this.VisitUnary(eNode, context); - // break; - //case INCDEC: - // result = this.VisitIncDec(eNode, context); - // break; - //case EQUALITY: result = this.VisitEquality(eNode, context); break; - //case DECISION: result = this.VisitDecision(eNode, context); break; - //case METHODCALL: result = this.VisitMethodCall(eNode, context); break; - //case NEW: result = this.VisitNew(eNode, context); break; - //case JSONASSIGN: result = this.VisitJsonAssign(eNode, context); break; - //case ARRAYACCESS: result = this.VisitArrayAccess(eNode, context); break; - //default: - // Guard.raise("Type isn't implemented: " + eNode.type); - } - - this._deep = this._deep - 1; - return result; - }, - - VisitArrayLiteral: function(eNode, context) { - /// - var self = this; - var items = eNode.items.map(function (item) { - return self.Visit(item, context); - }); - var result = Container.createArrayLiteralExpression(items); - return result; - }, - - VisitObjectLiteral: function(eNode, context) { - /// - var self = this; - var members = eNode.members.map(function (member) { - return self.Visit(member, context); - }); - var result = Container.createObjectLiteralExpression(members); - return result; - }, - - VisitObjectField: function(eNode, context) { - /// - var expression = this.Visit(eNode.expression, context); - var result = Container.createObjectFieldExpression(eNode.fieldName, expression); - return result; - }, - - VisitThis: function (eNode, context) { - return eNode; - }, - VisitCall: function (eNode, context) { - /// - var self = this; - var args = eNode.args.map(function (arg) { return this.Visit(arg, context); }, this); - var expression = this.Visit(eNode.expression, context); - var member = this.Visit(eNode.member, context); - return new $data.Expressions.CallExpression(expression, member, args); - }, - - VisitParameter: function(eNode, context) { - /// - /// - //var result = new $data.Expressions.ParameterExpression(eNode.name, eNode.type, eNode.nodeType); - return eNode; - }, - - VisitConstant: function (eNode, context) { - /// - /// - //var result = new $data.Expressions.ParameterExpression(eNode.name, eNode.type, eNode.nodeType); - return eNode; - }, - - VisitFunction: function(eNode, context) { - /// - var self = this; - - var params = eNode.parameters.map(function (p, i) { - return self.Visit(p, context); - }); - - var body = self.Visit(eNode.body, context); - var result = new $data.Expressions.FunctionExpression(eNode.name, params, body); - return result; - }, - - VisitBinary: function (eNode, context) { - /// - /// - /// - // - - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - return new $data.Expressions.SimpleBinaryExpression(left, right, eNode.nodeType, eNode.operator, eNode.type); - }, - - VisitProperty: function (eNode, context) { - /// - var expression = this.Visit(eNode.expression, context); - var member = this.Visit(eNode.member, context); - return new $data.Expressions.PropertyExpression(expression, member); - //var member = - }, - - VisitUnary: function (eNode, context) { - /// - /// - /// - /// - var operand = this.Visit(eNode.operand, context); - if (operand === eNode.operand) - return eNode; - return new $data.Expressions.UnaryExpression(operand, eNode.operator, eNode.nodeType); - }, - - VisitEntityContext: function (eNode, context) { - /// - /// - //var result = new $data.Expressions.ParameterExpression(eNode.name, eNode.type, eNode.nodeType); - return eNode; - }, - - VisitDecision: function (eNode, context) { - /// - /// - /// - // - - var expression = this.Visit(eNode.expression, context); - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - if (expression === eNode.expression && left === eNode.left && right === eNode.right) - return eNode; - return $data.Expressions.ExpressionNodeTypes.DecisionExpressionNode.create(eNode.executable, expression, left, right); - }, - - VisitNew: function (eNode, context) { - /// - /// - /// - // - - var values = this.VisitArray(eNode.values, context); - if (values === eNode.values) - return eNode; - return $data.Expressions.ExpressionNodeTypes.NewExpressionNode.create(true, values); - }, - VisitArrayAccess: function (eNode, context) { - /// - /// - /// - // - - var array = this.Visit(eNode.array, context); - var index = this.Visit(eNode.index, context); - if (array === eNode.array && index === eNode.index) - return eNode; - return $data.Expressions.ExpressionNodeTypes.ArrayAccessExpressionNode.create(true, array, index); - }, - VisitArray: function (eNodes, context) { - var args = []; - var ok = true; - for (var i = 0; i < eNodes.length; i++) { - args[i] = this.Visit(eNodes[i], context); - ok = ok && args[i] === eNodes[i]; - } - return ok ? eNodes : args; - }, - GetMemberChain: function (memberAccess, context) { - // { type:MEMBERACCESS, executable:true, expression:, member: } - if (memberAccess.expression.type == MEMBERACCESS) { - var a = this.GetMemberChain(memberAccess.expression, context); - a.push(memberAccess.member); - return a; - } - return [memberAccess.expression, memberAccess.member]; - } - }, {});$C("$data.Expressions.ParameterProcessor", $data.Expressions.ExpressionVisitor, null, { - constructor: function () { - ///Provides a base class for several ParameterProcessors like GlobalParameterProcessor or LambdaParameterProcessor - }, - - Visit: function (node, context) { - if ((node instanceof $data.Expressions.ParameterExpression || - node instanceof $data.Expressions.ThisExpression) - && this.canResolve(node)) { - var result = this.resolve(node, context); - if (result !== node) - result["resolvedBy"] = this.constructor.name; - return result; - } else { - return node; - } - }, - - canResolve: function (paramExpression) { - /// - Guard.raise("Pure method"); - }, - resolve: function (paramExpression) { - /// - Guard.raise("Pure method"); - } -}); -$C("$data.Expressions.GlobalContextProcessor", $data.Expressions.ParameterProcessor, null, { - constructor: function (global) { - /// - this.global = global; - }, - - canResolve: function (paramExpression) { - /// - return paramExpression.nodeType == $data.Expressions.ExpressionType.Parameter && this.global && typeof this.global === 'object' && - paramExpression.name in this.global; - }, - - resolve: function (paramExpression) { - /// - /// - var resultValue = this.global[paramExpression.name]; - var expression = Container.createConstantExpression(resultValue, typeof resultValue, paramExpression.name); - return expression; - } - -}); - - - -$C("$data.Expressions.ConstantValueResolver", $data.Expressions.ParameterProcessor, null, { - constructor: function (paramsObject, global, scopeContext) { - /// - this.globalResolver = Container.createGlobalContextProcessor(global); - this.paramResolver = Container.createGlobalContextProcessor(paramsObject); - this.paramsObject = paramsObject; - this.scopeContext = scopeContext; - }, - - canResolve: function (paramExpression) { - /// - return (paramExpression.name === '$context') || (paramExpression.nodeType == $data.Expressions.ExpressionType.This && this.paramsObject) - ? true : (this.paramResolver.canResolve(paramExpression) || this.globalResolver.canResolve(paramExpression)); - }, - - resolve: function (paramExpression) { - /// - /// - if (paramExpression.name === '$context') { - return Container.createEntityContextExpression(this.scopeContext); - } - if (paramExpression.nodeType == $data.Expressions.ExpressionType.This) { - return Container.createConstantExpression(this.paramsObject, typeof this.paramsObject, 'this'); - } - return this.paramResolver.canResolve(paramExpression) ? this.paramResolver.resolve(paramExpression) : this.globalResolver.resolve(paramExpression); - } - -});$C("$data.Expressions.LocalContextProcessor", $data.Expressions.GlobalContextProcessor, null, { - constructor: function (evalMethod) { - /// - this.canResolve = function (paramExpression) { - /// - return paramExpression.nodeType == $data.Expressions.ExpressionType.Parameter && - (evalMethod("typeof " + paramExpression.name) !== 'undefined'); - }; - this.resolve = function(paramExpression) { - /// - /// - var resultValue = evalMethod(paramExpression.name); - var expression = Container.createConstantExpression(resultValue, typeof resultValue); - return expression; - }; - - } - }); -$C("$data.Expressions.LambdaParameterProcessor", $data.Expressions.ParameterProcessor, null, { - constructor: function (lambdaParameterTypeInfos) { - /// - /// - var paramIndices = {}; - var $idx = "name"; - - this.canResolve = function (paramExpression, context) { - if (paramExpression.nodeType == $data.Expressions.ExpressionType.LambdaParameter) { - var fnParams = paramExpression.owningFunction.parameters; - - if (fnParams.length == 1 && paramExpression.name == fnParams[0].name) { - paramIndices[paramExpression.name] = lambdaParameterTypeInfos[0]; - return true; - } - - for (var j = 0; j < fnParams.length; j++) { - if (fnParams[j].name == paramExpression.name) { - paramIndices[paramExpression.name] = lambdaParameterTypeInfos[j]; - return true; - } - } - return false; - } - return false; - }; - - this.resolve = function(paramExpression, context) { - var lambdaParamType = paramIndices[paramExpression.name]; - var result = Container.createParameterExpression(paramExpression.name, - lambdaParamType, - $data.Expressions.ExpressionType.LambdaParameter); - result.owningFunction = paramExpression.owningFunction; - return result; - }; - } - -}); -$C('$data.Expressions.ParameterResolverVisitor', $data.Expressions.ExpressionVisitor, null, { - - constructor: function (expression, resolver) { - /// - /// ParameterResolverVisitor traverses the JavaScript Code Expression tree and converts - /// outer but otherwise execution local variable references into ConstantExpressions-t. - /// for example: context.Persons.filter(function(p) { return p.Name == document.location.href }) - /// is transformed into a constant that has the current href as its value - /// - /// - /// - this.lambdaParamCache = {}; - }, - - Visit: function (expression, resolver) { - /// - /// - //TODO base call is just ugly - return $data.Expressions.ExpressionVisitor.prototype.Visit.call(this, expression, resolver); - - }, - - - VisitArrayLiteral: function(eNode, context) { - var self = this; - var items = eNode.items.map(function (item) { return self.Visit(item, context); }); - var allLocal = items.every(function (item) { - return item instanceof $data.Expressions.ConstantExpression; - }); - - if (allLocal) { - items = items.map(function (item) { return item.value }); - return Container.createConstantExpression(items, "array"); - } else { - return Container.createArrayLiteralExpression(items); - } - }, - - VisitObjectLiteral: function(eNode, context) { - var self = this; - var members = eNode.members.map(function (item) { return self.Visit(item, context); }); - var allLocal = members.every(function (member) { - return member.expression instanceof $data.Expressions.ConstantExpression; - }); - - if (allLocal) { - var params = members.map(function (member) { return { name: member.fieldName, value: member.expression.value }; }); - var value = eNode.implementation(params); - return Container.createConstantExpression(value, typeof value); - } else { - return Container.createObjectLiteralExpression(members); - } - }, - - VisitThis: function(eNode, resolver) { - return resolver.Visit(eNode, resolver); - }, - - VisitParameter: function(eNode, resolver) { - /// - /// - /// - - var node; - ///TODO let the resolver handle lambdaReferences if it wants to deal with it - switch(eNode.nodeType){ - case $data.Expressions.ExpressionType.Parameter: - case $data.Expressions.ExpressionType.LambdaParameter: - node = resolver.Visit(eNode, resolver); - if (node.nodeType == $data.Expressions.ExpressionType.LambdaParameter) { - this.lambdaParamCache[node.name] = node; - } - return node; - case $data.Expressions.ExpressionType.LambdaParameterReference: - var lambdaParam = this.lambdaParamCache[eNode.name]; - if (lambdaParam) { - node = Container.createParameterExpression(eNode.name, - lambdaParam.type, - $data.Expressions.ExpressionType.LambdaParameterReference); - node.paramIndex = eNode.paramIndex; - //node.typeName = lambdaParam.type.name || lambdaParam.type; - return node; - } - break; - default: - return eNode; - - } - - - return eNode; - }, - - VisitConstant: function (eNode, context) { - /// - /// - return eNode; - }, - - VisitFunction: function(eNode, context) { - /// - - var self = this; - var params = eNode.parameters.map(function (p, i) { - var result = self.Visit(p, context); - return result; - }); - var body = self.Visit(eNode.body, context); - var result = new $data.Expressions.FunctionExpression(eNode.name, params, body); - - return result; - }, - - VisitBinary: function (eNode, context) { - /// - /// - /// - /// - - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - var expr = $data.Expressions; - - if (left instanceof expr.ConstantExpression && right instanceof expr.ConstantExpression) - { - var result = eNode.implementation(left.value, right.value); - return Container.createConstantExpression(result, typeof result); - } - return new Container.createSimpleBinaryExpression(left, right, eNode.nodeType, eNode.operator, eNode.type); - }, - - VisitUnary: function (eNode, context) { - /// - /// - /// - /// - - var operand = this.Visit(eNode.operand, context); - //var imp = $data.unaryOperators.getOperator( - var expr = $data.Expressions; - if (operand instanceof expr.ConstantExpression) - { - var result = eNode.operator.implementation(operand.value); - return Container.createConstantExpression(result, typeof result); - } - return new Container.createUnaryExpression(operand, eNode.operator, eNode.nodeType); - }, - - VisitProperty: function (eNode, context) { - /// - var expression = this.Visit(eNode.expression, context); - var member = this.Visit(eNode.member, context); - var result; - if (expression instanceof $data.Expressions.ConstantExpression && - member instanceof $data.Expressions.ConstantExpression) { - ///TODO implement checking for the member, throw on error - result = eNode.implementation(expression.value, member.value); - - //Method call processed before - //if (typeof result === 'function') { - // return new $data.Expressions.ConstantExpression( - // function () { return result.apply(expression.value, arguments); }); - //} - return Container.createConstantExpression(result, typeof result, expression.name + '$' + member.value); - } - if (expression === eNode.expression && member === eNode.member) - return eNode; - - result = Container.createPropertyExpression(expression, member); - return result; - }, - - VisitCall: function (eNode, context) { - /// - function isExecutable(args, body, obj) { - return body instanceof $data.Expressions.ConstantExpression && - //global methods will not have a this. - (!obj || obj instanceof $data.Expressions.ConstantExpression) && - args.every(function(item) { - return item instanceof $data.Expressions.ConstantExpression; - }); - } - var call = $data.Expressions.ExpressionVisitor.prototype.VisitCall.apply(this, arguments); - var obj = call.expression; - var body = call.member; - var args = call.args; - - function convertToValue(arg) { - if (arg instanceof $data.Expressions.ConstantExpression) - return arg.value; - return arg; - }; - - if (isExecutable(args, body, obj)) { - var fn = body.value; - if (typeof fn === 'string' && obj.value) { - fn = obj.value[fn]; - } - if (typeof fn !== 'function') { - //TODO dig that name out from somewhere - Guard.raise("Constant expression is not a method..."); - } - var value = eNode.implementation(obj.value, fn, args.map(convertToValue)); - return new $data.Expressions.ConstantExpression(value, typeof value); - } - return call; - } -}, {}); -$C("$data.Expressions.AggregatedVisitor", $data.Expressions.ExpressionVisitor, null, { - constructor: function (visitors) { - /// - - this.Visit = function (node, context) { - for (var i = 0; i < visitors.length; i++) { - var n = visitors[i].Visit(node, context); - if (n !== node) - return n; - } - return node; - }; - } - -}); -//"use strict"; // suspicious code - -$C('$data.Expressions.LogicalSchemaBinderVisitor', - $data.Expressions.ExpressionVisitor, null, - { - constructor: function (expression, binder) { - - }, - - VisitProperty: function (expression, context) { - /// - var exp = this.Visit(expression.expression, context); - var mem = this.Visit(expression.member, context); - - var type = exp.type; - var memberType = context.memberResolver.resolve(type, mem.value); - mem.type = memberType; - return Container.createPropertyExpression(exp, mem); - } - - }, {});$data.Class.define('$data.Expressions.ExpTreeVisitor', - null, null, - { - constructor: function () { - this._deep = 0; - }, - Visit: function (eNode, context) { - /// - /// - /// - // - this._deep = this._deep + 1; - var result = null; - switch (eNode.type) { - case LITERAL: result = this.VisitLiteral(eNode, context); break; - case VARIABLE: result = this.VisitVariable(eNode, context); break; - case MEMBERACCESS: result = this.VisitMember(eNode, context); break; - case BINARY: result = this.VisitBinary(eNode, context); break; - case UNARY: result = this.VisitUnary(eNode, context); break; - case INCDEC: result = this.VisitIncDec(eNode, context); break; - case EQUALITY: result = this.VisitEquality(eNode, context); break; - case DECISION: result = this.VisitDecision(eNode, context); break; - case METHODCALL: result = this.VisitMethodCall(eNode, context); break; - case NEW: result = this.VisitNew(eNode, context); break; - case JSONASSIGN: result = this.VisitJsonAssign(eNode, context); break; - case ARRAYACCESS: result = this.VisitArrayAccess(eNode, context); break; - default: - Guard.raise("Type isn't implemented: " + eNode.type); - } - this._deep = this._deep - 1; - return result; - }, - VisitLiteral: function (eNode, context) { - /// - /// - /// - // - - return eNode; - }, - VisitVariable: function (eNode, context) { - /// - /// - /// - // - - return eNode; - }, - VisitMember: function (eNode, context) { - /// - /// - /// - // - - var expression = this.Visit(eNode.expression, context); - var member = this.Visit(eNode.member, context); - if (expression === eNode.expression && member === eNode.member) - return eNode; - return $data.Expressions.ExpressionNodeTypes.MemberAccessExpressionNode.create(eNode.executable, expression, member); - }, - VisitBinary: function (eNode, context) { - /// - /// - /// - // - - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - if (left === eNode.left && right === eNode.right) - return eNode; - return $data.Expressions.ExpressionNodeTypes.BinaryExpressionNode.create(eNode.executable, eNode.operator, left, right); - }, - VisitUnary: function (eNode, context) { - /// - /// - /// - // - - var operand = this.Visit(eNode.operand, context); - if (operand === eNode.operand) - return eNode; - return $data.Expressions.ExpressionNodeTypes.UnaryExpressionNode.create(eNode.executable, eNode.operator, operand); - }, - VisitIncDec: function (eNode, context) { - /// - /// - /// - // - - var operand = this.Visit(eNode.operand, context); - if (operand === eNode.operand) - return eNode; - return $data.Expressions.ExpressionNodeTypes.IncDecExpressionNode.create(eNode.executable, eNode.operator, operand, eNode.suffix); - }, - VisitEquality: function (eNode, context) { - /// - /// - /// - // - - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - if (left === eNode.left && right === eNode.right) - return eNode; - return $data.Expressions.ExpressionNodeTypes.EqualityExpressionNode.create(eNode.executable, eNode.operator, left, right); - }, - VisitDecision: function (eNode, context) { - /// - /// - /// - // - - var expression = this.Visit(eNode.expression, context); - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - if (expression === eNode.expression && left === eNode.left && right === eNode.right) - return eNode; - return $data.Expressions.ExpressionNodeTypes.DecisionExpressionNode.create(eNode.executable, expression, left, right); - }, - VisitMethodCall: function (eNode, context) { - /// - /// - /// - // - - var object = eNode.object ? this.Visit(eNode.object, context) : null; - var args = this.VisitArray(eNode.args, context); - if (object === eNode.object && args === eNode.args) - return eNode; - return $data.Expressions.ExpressionNodeTypes.MethodcallExpressionNode.create(eNode.executable, object, eNode.method, args); - }, - VisitNew: function (eNode, context) { - /// - /// - /// - // - - var values = this.VisitArray(eNode.values, context); - if (values === eNode.values) - return eNode; - return $data.Expressions.ExpressionNodeTypes.NewExpressionNode.create(true, values); - }, - VisitJsonAssign: function (eNode, context) { - /// - /// - /// - // - - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - if (left === eNode.left && right === eNode.right) - return eNode; - left.JSONASSIGN = true; - right.JSONASSIGN = true; - return $data.Expressions.ExpressionNodeTypes.JsonAssignExpressionNode.create(true, left, right); - }, - VisitArrayAccess: function (eNode, context) { - /// - /// - /// - // - - var array = this.Visit(eNode.array, context); - var index = this.Visit(eNode.index, context); - if (array === eNode.array && index === eNode.index) - return eNode; - return $data.Expressions.ExpressionNodeTypes.ArrayAccessExpressionNode.create(true, array, index); - }, - VisitArray: function (eNodes, context) { - var args = []; - var ok = true; - for (var i = 0; i < eNodes.length; i++) { - args[i] = this.Visit(eNodes[i], context); - ok = ok && args[i] === eNodes[i]; - } - return ok ? eNodes : args; - }, - GetMemberChain: function (memberAccess, context) { - // { type:MEMBERACCESS, executable:true, expression:, member: } - if (memberAccess.expression.type == MEMBERACCESS) { - var a = this.GetMemberChain(memberAccess.expression, context); - a.push(memberAccess.member); - return a; - } - return [memberAccess.expression, memberAccess.member]; - } - }, {});$data.Class.define('$data.Expressions.SetExecutableVisitor', $data.Expressions.ExpTreeVisitor, null, -{ - Visit: function (eNode, context) { - switch (eNode.type) { - case LITERAL: return this.VisitLiteral(eNode, context); - case VARIABLE: return this.VisitVariable(eNode, context); - case MEMBERACCESS: return this.VisitMember(eNode, context); - case BINARY: return this.VisitBinary(eNode, context); - case UNARY: return this.VisitUnary(eNode, context); - case INCDEC: return this.VisitIncDec(eNode, context); - case EQUALITY: return this.VisitEquality(eNode, context); - case DECISION: return this.VisitDecision(eNode, context); - case METHODCALL: return this.VisitMethodCall(eNode, context); - case NEW: return this.VisitNew(eNode, context); - case JSONASSIGN: return this.VisitJsonAssign(eNode, context); - case ARRAYACCESS: return this.VisitArrayAccess(eNode, context); - default: - Guard.raise("Type isn't implemented: " + eNode.type); - } - }, - - VisitBinary: function (eNode, context) { - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - if (left === eNode.left && right === eNode.right && (left.executable && right.executable == eNode.executable)) - return eNode; - return $data.Expressions.ExpressionNodeTypes.BinaryExpressionNode.create(left.executable && right.executable, eNode.operator, left, right); - }, - VisitUnary: function (eNode, context) { - var operand = this.Visit(eNode.operand, context); - if (operand === eNode.operand) - return eNode; - return $data.Expressions.ExpressionNodeTypes.UnaryExpressionNode.create(operand.executable, eNode.operator, operand); - }, - VisitIncDec: function (eNode, context) { - var operand = this.Visit(eNode.operand, context); - if (operand === eNode.operand) - return eNode; - return $data.Expressions.ExpressionNodeTypes.IncDecExpressionNode.create(operand.executable, eNode.operator, operand, eNode.suffix); - }, - VisitEquality: function (eNode, context) { - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - if (left === eNode.left && right === eNode.right && (left.executable && right.executable == eNode.executable)) - return eNode; - return $data.Expressions.ExpressionNodeTypes.EqualityExpressionNode.create(left.executable && right.executable, eNode.operator, left, right); - }, - VisitDecision: function (eNode, context) { - var expression = this.Visit(eNode.expression, context); - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - if (expression === eNode.expression && left === eNode.left && right === eNode.right && (left.executable && right.executable && expression.executable == eNode.executable)) - return eNode; - return $data.Expressions.ExpressionNodeTypes.DecisionExpressionNode.create(left.executable && right.executable && expression.executable, expression, left, right); - }, - VisitMethodCall: function (eNode, context) { - var object = eNode.object ? this.Visit(eNode.object, context) : null; - var args = this.VisitArray(eNode.args, context); - if (object === eNode.object && args === eNode.args && ((object == null ? true : object.executable) == eNode.executable)) - return eNode; - return $data.Expressions.ExpressionNodeTypes.MethodcallExpressionNode.create(object == null ? true : object.executable, object, eNode.method, args); - }, - VisitNew: function (eNode, context) { - // { type:NEW, executable:true, values: [] }; - var values = this.VisitArray(eNode.values, context); - if (values === eNode.values) - return eNode; - return $data.Expressions.ExpressionNodeTypes.NewExpressionNode.create(true, values); - }, - VisitJsonAssign: function (eNode, context) { - // { type:JSONASSIGN, executable:true, left: variable, right: right } - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - if (left === eNode.left && right === eNode.right) - return eNode; - left.JSONASSIGN = true; - right.JSONASSIGN = true; - return $data.Expressions.ExpressionNodeTypes.JsonAssignExpressionNode.create(true, left, right); - }, - VisitArrayAccess: function (eNode, context) { - // { type:ARRAYACCESS, executable:true, array:, index: } - var array = this.Visit(eNode.array, context); - var index = this.Visit(eNode.index, context); - if (array === eNode.array && index === eNode.index) - return eNode; - return $data.Expressions.ExpressionNodeTypes.ArrayAccessExpressionNode.create(true, array, index); - }, - VisitArray: function (eNodes, context) { - var args = []; - var ok = true; - for (var i = 0; i < eNodes.length; i++) { - args[i] = this.Visit(eNodes[i], context); - ok = ok && args[i] === eNodes[i]; - } - return ok ? eNodes : args; - }, - - VisitLiteral: function (eNode, context) { - return { type: eNode.type, executable: true, value: eNode.value, valueType: eNode.valueType }; - }, - VisitVariable: function (eNode, context) { - if (typeof context.paramContext[eNode.name] == undefined) // isn't param //TODO: check ParamContext - Guard.raise("Variable is not defined in the paramContext: " + eNode.name); - //this._setExecutable(eNode, true); - return $data.Expressions.ExpressionNodeTypes.VariableExpressionNode.create(true, "Math", "GLOBALOBJECT"); - }, - VisitMember: function (eNode, context) { - var chain = this.GetMemberChain(eNode); - var firstMember = chain[0].name; - var isLambdaParam = context.lambdaParams.indexOf(firstMember) >= 0; - var isLocalParam = firstMember == context.paramsName; //TODO: check ParamContext // old: typeof context.paramContext[firstMember] != "undefined"; - if (!isLocalParam && !isLambdaParam) - Guard.raise("Variable is not defined in the paramContext or the lambda parameters: " + firstMember); - - return $data.Expressions.ExpressionNodeTypes.MemberAccessExpressionNode.create(isLocalParam, eNode.expression, eNode.member); - } -}, null);$data.Class.define('$data.Expressions.ExecutorVisitor', $data.Expressions.ExpTreeVisitor, null, -{ - //-- - VisitVariable: function (eNode, context) { - if (!eNode.executable) - return eNode; - var value = (eNode.name == context.paramsName) ? context.paramContext : window[eNode.name]; - if (typeof value == 'undefined') - Guard.raise( - new Exception("Unknown variable in '" + context.operation + "' operation. The variable isn't referenced in the parameter context and it's not a global variable: '" + eNode.name + "'.", - "InvalidOperation", { operationName: context.operation, missingParameterName: eNode.name }) - ); - return $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, typeof value, value); - }, - VisitMember: function (eNode, context) { - if (!eNode.executable) - return eNode; - var chain = this.GetMemberChain(eNode); - var value; - for (var i = 0; i < chain.length; i++) { - if (i == 0) - value = context.paramContext; - else - value = value[chain[i].name]; - } - return $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, typeof value, value); - - - }, - VisitUnary: function (eNode, context) { - var operand = this.Visit(eNode.operand, context); - if (operand !== eNode.operand) - eNode = $data.Expressions.ExpressionNodeTypes.UnaryExpressionNode.create(eNode.executable, eNode.operator, operand); - if (!eNode.executable) - return eNode; - // executing and returning with result as a literal - var value; - var src; - var operandValue = ((operand.valueType == "string") ? ("'" + operand.value + "'") : operand.value); - src = "value = " + eNode.operator + " " + operandValue; - eval(src); - - return $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, typeof value, value); - }, - VisitIncDec: function (eNode, context) { - var operand = this.Visit(eNode.operand, context); - if (operand !== eNode.operand) - eNode = $data.Expressions.ExpressionNodeTypes.IncDecExpressionNode.create(eNode.executable, eNode.operator, operand, eNode.suffix); - if (!eNode.executable) - return eNode; - // executing and returning with result as a literal - var value; - if (eNode.suffix) - value = eNode.operator == "++" ? operand.value++ : operand.value--; - else - value = eNode.operator == "++" ? ++operand.value : --operand.value; - return $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, typeof value, value); - }, - VisitBinary: function (eNode, context) { - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - if (left !== eNode.left || right !== eNode.right) - eNode = $data.Expressions.ExpressionNodeTypes.BinaryExpressionNode.create(eNode.executable, eNode.operator, left, right); - if (!eNode.executable) - return eNode; - // executing and returning with result as a literal - var value; - var src; - var leftValue = ((left.valueType == "string") ? ("'" + left.value + "'") : left.value); - var rightValue = ((right.valueType == "string") ? ("'" + right.value + "'") : right.value); - src = "value = " + leftValue + " " + eNode.operator + " " + rightValue; - eval(src); - - return $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, typeof value, value); - }, - VisitEquality: function (eNode, context) { - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - if (left !== eNode.left || right !== eNode.right) - eNode = $data.Expressions.ExpressionNodeTypes.EqualityExpressionNode.create(eNode.executable, eNode.operator, left, right); - if (!eNode.executable) - return eNode; - // executing and returning with result as a literal - var value; - var src; - var leftValue = ((left.valueType == "string") ? ("'" + left.value + "'") : left.value); - var rightValue = ((right.valueType == "string") ? ("'" + right.value + "'") : right.value); - src = "value = " + leftValue + " " + eNode.operator + " " + rightValue; - eval(src); - return $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, typeof value, value); - }, - VisitDecision: function (eNode, context) { - var expression = this.Visit(eNode.expression, context); - var left = this.Visit(eNode.left, context); - var right = this.Visit(eNode.right, context); - if (expression !== eNode.expression || left !== eNode.left || right !== eNode.right) - eNode = $data.Expressions.ExpressionNodeTypes.DecisionExpressionNode.create(eNode.executable, expression, left, right); - if (!eNode.executable) - return eNode; - // executing and returning with result as a literal - var value = expression.value ? left.value : right.value; - return $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, typeof value, value); - }, - VisitMethodCall: function (eNode, context) { - var object = eNode.object ? this.Visit(eNode.object, context) : null; - var args = this.VisitArray(eNode.args, context); - if (object !== eNode.object || args != eNode.args) - eNode = $data.Expressions.ExpressionNodeTypes.MethodcallExpressionNode.create(eNode.executable, object, eNode.method, args); - if (!eNode.executable) - return eNode; - // executing and returning with result as a literal - var a = []; - for (var i = 0; i < args.length; i++) { - var arg = args[i]; - var t = typeof arg.value; - a.push((t == "string") ? ("'" + arg.value + "'") : arg.value); - } - var value; - var src = object ? - "value = object.value[eNode.method](" + a.join(",") + ");" - : - "value = " + eNode.method + "(" + a.join(",") + ");"; - eval(src); - - return $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, typeof value, value); - }, - VisitArrayAccess: function (eNode, context) { - // { type:ARRAYACCESS, executable:true, array:, index: } - var arrayNode = this.Visit(eNode.array, context); - var indexNode = this.Visit(eNode.index, context); - var value = arrayNode.value[indexNode.value]; - return $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, typeof value, value); - } -}, null); $data.Class.define('$data.Expressions.ExpressionBuilder', null, null, -{ - constructor: function (context) { - this.context = context; - }, - _isLambdaParam: function (name) { - var p = this.context.lambdaParams; - for (var i = 0; i < p.length; i++) { - if (p[i] == name) - return true; - } - return false; - }, - _isParam: function (name) { - return this.context.paramContext[name] != undefined; - }, - _isParamRoot: function (name) { - return this.context.paramsName == name; - }, - Build: function (node, expNode) { - var n; - switch (node.arity) { - case "infix": - if ("(" == node.value) - n = this.BuildMethodCall(node, expNode); - else if ("." == node.value) - n = this.BuildMember(node, expNode); - else if (["===", "==", "!==", "!=", ">", "<", ">=", "<="].indexOf(node.value) >= 0) - n = this.BuildEquality(node, expNode); - else if (["&&", "||"].indexOf(node.value) >= 0) - n = this.BuildBinary(node, expNode); - else if (["+", "-", "*", "/", "%"].indexOf(node.value) >= 0) - n = this.BuildBinary(node, expNode); - else if ("[" == node.value) - n = this.BuildArrayAccess(node, expNode); - else - Guard.raise("Value of infix node isn't implemented: " + node.value); - break; - case "prefix": - if (["+", "-", "!"].indexOf(node.value) >= 0) - n = this.BuildUnary(node, expNode); - else if (["++", "--"].indexOf(node.value) >= 0) - n = this.BuildIncDec(node, expNode); - else if ("{" == node.value/* && "object" == node.type*/) //TODO: check the second condition necessity - n = this.BuildNewExpression(node, expNode); - else - Guard.raise("Value of prefix node isn't implemented: " + node.value); - break; - case "suffix": - if (["++", "--"].indexOf(node.value) >= 0) - n = this.BuildIncDec(node, expNode); - else - Guard.raise("Value of suffix node isn't implemented: " + node.value); - break; - case "string": - case "number": - n = this.BuildLiteral(node, expNode); //TODO: more arity to literal? - break; - case "ternary": - if (node.value == "?") - n = this.BuildDecision(node, expNode); - else - Guard.raise("Value of ternary node isn't implemented: " + node.value); - break; - case null: - case undefined: - if (node.type == "boolean" && (node.value == "true" || node.value == "false")) - n = this.BuildBoolLiteral(node, expNode); - else - n = this.BuildVariable(node, expNode); - break; - default: - Guard.raise("Arity isn't implemented: " + node.arity); - } - return n; - }, - BuildNewExpression: function (node, expNode) { - var newExpression = $data.Expressions.ExpressionNodeTypes.NewExpressionNode.create(true, []); - var n = node.first; - for (var i = 0; i < n.length; i++) - newExpression.values.push(this.Build(n[i], newExpression)); - return newExpression; - }, - BuildLiteral: function (node, expNode) { - return $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, node.arity, node.value); - }, - BuildBoolLiteral: function (node, expNode) { - return $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, node.type, node.value == "true" ? true : false); - }, - BuildVariable: function (node, expNode) { - if (!node.first) { - if (expNode.type == MEMBERACCESS) { - var subType; - if (this._isLambdaParam(node.value)) - subType = "LAMBDAPARAM"; - else if (this._isParamRoot(node.value)) - subType = "PARAMETERROOT"; - else if (this._isParam(node.value)) - subType = "PARAMETER"; - else - subType = "PROPERTY"; - } - else { - if (this._isLambdaParam(node.value)) - subType = "LAMBDAPARAM"; - else if (this._isParamRoot(node.value)) - subType = "PARAMETERROOT"; - else if (this._isParam(node.value)) - subType = "PARAMETER"; - else if (window[node.value] != undefined) - subType = "GLOBALOBJECT"; - else - Guard.raise( - new Exception("Unknown variable in '" + this.context.operation + "' operation. The variable isn't referenced in the parameter context and it's not a global variable: '" + node.value + "'.", - "InvalidOperation", { operationName: this.context.operation, missingParameterName: node.value }) - ); - } - return $data.Expressions.ExpressionNodeTypes.VariableExpressionNode.create(true, node.value, subType); - } - - var left = $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, "name", node.value); - - var jsonAssign = $data.Expressions.ExpressionNodeTypes.JsonAssignExpressionNode.create(true); - var right = this.Build(node.first, jsonAssign); - //left.parent = jsonAssign; - jsonAssign.left = left; - jsonAssign.right = right; - - left.JSONASSIGN = true; - right.JSONASSIGN = true; - - return jsonAssign; - }, - BuildMember: function (node, expNode) { - if (node.value != "." || node.arity != "infix") { - if (node.type == "string") { //TODO: more types? - return $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, node.arity, node.value); - } - return $data.Expressions.ExpressionNodeTypes.MemberAccessExpressionNode.create(true, null, node.value); - } - var result = $data.Expressions.ExpressionNodeTypes.MemberAccessExpressionNode.create(true); - var expression = this.Build(node.first, result); - var member = this.Build(node.second, result); - result.expression = expression; - result.member = member; - return result; - }, - BuildUnary: function (node, expNode) { - var result = $data.Expressions.ExpressionNodeTypes.UnaryExpressionNode.create(true, node.value); - result.operand = this.Build(node.first, result); - return result; - }, - BuildIncDec: function (node, expNode) { - var result = $data.Expressions.ExpressionNodeTypes.IncDecExpressionNode.create(true, node.value, null, node.arity == "suffix"); - result.operand = this.Build(node.first, result); - return result; - }, - BuildBinary: function (node, expNode) { - if (!node.first) Guard.raise("Cannot build binary: node.first is null"); - if (!node.second) Guard.raise("Cannot build binary: node.second is null"); - var result = $data.Expressions.ExpressionNodeTypes.BinaryExpressionNode.create(true, node.value); - result.left = this.Build(node.first, result); - result.right = this.Build(node.second, result); - return result; - }, - BuildEquality: function (node, expNode) { - var result = $data.Expressions.ExpressionNodeTypes.EqualityExpressionNode.create(true, node.value); - result.left = this.Build(node.first, result); - result.right = this.Build(node.second, result); - return result; - }, - BuildDecision: function (node, expNode) { - var result = $data.Expressions.ExpressionNodeTypes.DecisionExpressionNode.create(true); - result.expression = this.Build(node.first, result); - result.left = this.Build(node.second, result); - result.right = this.Build(node.third, result); - return result; - }, - BuildMethodCall: function (node, expNode) { - var result = $data.Expressions.ExpressionNodeTypes.MethodcallExpressionNode.create(true); - if (node.first.type == "function") { - //-- object's function - result.object = this.Build(node.first.first, result); - result.method = node.first.second.value; - } - else { - //-- global function - if (node.first.type != null) - Guard.raise("Cannot build MethodCall because type is " + type); - result.object = null; - result.method = node.first.value; - } - var argNodes = node.second; - var args = []; - for (var i = 0; i < argNodes.length; i++) { - var arg = argNodes[i]; - args[i] = this.Build(arg, result); - } - result.args = args; - return result; - }, - BuildArrayAccess: function (node, expNode) { - // { type:ARRAYACCESS, executable:true, array:, index: } - var result = $data.Expressions.ExpressionNodeTypes.ArrayAccessExpressionNode.create(true); - result.array = this.Build(node.first, result); - result.index = this.Build(node.second, result); - return result; - } -}, null);$C('$data.Expressions.AssociationInfoExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (associationInfo) { - this.associationInfo = associationInfo; - }, - nodeType: { value: $data.Expressions.ExpressionType.AssociationInfo, enumerable: true } -});$C('$data.Expressions.CodeExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (source, parameters) { - if (Container.resolveType(Container.getTypeName(source)) == $data.String && source.replace(/^[\s\xA0]+/, "").match("^function") != "function") { - source = "function (it) { return " + source + "; }"; - } - - this.source = source; - this.parameters = parameters; - }, - nodeType: { value: $data.Expressions.ExpressionType.Code, enumerable: true } -});$C('$data.Expressions.CodeToEntityConverter', $data.Expressions.ExpressionVisitor, null, { - constructor: function (scopeContext) { - ///This visitor converts a JS language tree into a semantical Entity Expression Tree This visitor should be invoked on a CodeExpression - ///context.thisArg contains parameters, context.lambdaParams should have an array value - this.scopeContext = scopeContext; - this.parameters = []; - - }, - - - VisitBinary: function (expression, context) { - var left = this.Visit(expression.left, context); - var right = this.Visit(expression.right, context); - - if ((!(left instanceof $data.Expressions.ConstantExpression) && right instanceof $data.Expressions.ConstantExpression) || - (!(right instanceof $data.Expressions.ConstantExpression) && left instanceof $data.Expressions.ConstantExpression)) { - - var refExpression, constExpr; - if (right instanceof $data.Expressions.ConstantExpression) { - refExpression = left; - constExpr = right; - } else { - refExpression = right; - constExpr = left; - } - - var memInfo; - if ((memInfo = refExpression.selector) instanceof $data.Expressions.MemberInfoExpression || - (memInfo = refExpression.operation) instanceof $data.Expressions.MemberInfoExpression) { - - - if (memInfo.memberDefinition && (memInfo.memberDefinition.type || memInfo.memberDefinition.dataType)) { - var fieldType = Container.resolveType(memInfo.memberDefinition.type || memInfo.memberDefinition.dataType); - var constExprType = Container.resolveType(constExpr.type); - - if (fieldType !== constExprType) { - - var value = constExpr.value; - if (expression.operator === $data.Expressions.ExpressionType.In) { - if (Array.isArray(value)) { - var resultExp = []; - for (var i = 0; i < value.length; i++) { - resultExp.push(new $data.Expressions.ConstantExpression(value[i], fieldType)); - } - value = resultExp; - fieldType = $data.Array; - } else { - fieldType = constExprType; - } - } - - if (right === constExpr) { - right = new $data.Expressions.ConstantExpression(value, fieldType, right.name); - } else { - left = new $data.Expressions.ConstantExpression(value, fieldType, left.name); - } - } - } - } - } - - var operatorResolution = this.scopeContext.resolveBinaryOperator(expression.nodeType, expression, context.frameType); - var result = Container.createSimpleBinaryExpression(left, right, expression.nodeType, expression.operator, expression.type, operatorResolution); - return result; - }, - - VisitUnary: function (expression, context) { - var operand = this.Visit(expression.operand, context); - var operatorResolution = this.scopeContext.resolveUnaryOperator(expression.nodeType, expression, context.frameType); - var result = Container.createUnaryExpression(operand, expression.operator, expression.nodeType, operatorResolution); - return result; - }, - - VisitParameter: function (expression, context) { - Guard.requireValue("context", context); - var et = $data.Expressions.ExpressionType; - switch (expression.nodeType) { - case et.LambdaParameterReference: - var result = Container.createEntityExpression(context.lambdaParameters[expression.paramIndex], { lambda: expression.name }); - return result; - case et.LambdaParameter: - //TODO: throw descriptive exception or return a value - break; - default: - Guard.raise("Global parameter " + expression.name + " not found. For query parameters use 'this.field' notation"); - break; - } - }, - - VisitThis: function (expression, context) { - ///converts the ThisExpression into a QueryParameterExpression tha't value will be evaluated and stored in this.parameters collection - var index = this.parameters.push({ name: "", value: undefined }) - 1; - var result = Container.createQueryParameterExpression("", index, context.queryParameters, undefined); - return result; - }, - - VisitFunction: function (expression, context) { - var result = $data.Expressions.ExpressionVisitor.prototype.VisitFunction.apply(this, arguments); - return result.body; - }, - - VisitCall: function (expression, context) { - //var exp = this.Visit(expression.expression); - var self = this; - var exp = this.Visit(expression.expression, context); - var member = this.Visit(expression.member, context); - var args = expression.args.map(function (arg) { - return self.Visit(arg, context); - }); - var result; - - ///filter=>function(p) { return p.Title == this.xyz.BogusFunction('asd','basd');} - switch (true) { - case exp instanceof $data.Expressions.QueryParameterExpression: - var argValues = args.map(function (a) { return a.value; }); - result = expression.implementation(exp.value, member.value, argValues); - //var args = expressions - return Container.createQueryParameterExpression(exp.name + "$" + member.value, exp.index, result, typeof result); - case exp instanceof $data.Expressions.EntityFieldExpression: - - case exp instanceof $data.Expressions.EntityFieldOperationExpression: - var operation = this.scopeContext.resolveFieldOperation(member.value, exp, context.frameType); - if (!operation) { - Guard.raise("Unknown entity field operation: " + member.getJSON()); - } - member = Container.createMemberInfoExpression(operation); - result = Container.createEntityFieldOperationExpression(exp, member, this._resolveFunctionArguments(args, operation.parameters)); - return result; - - case exp instanceof $data.Expressions.EntitySetExpression: - var operation = this.scopeContext.resolveSetOperations(member.value, exp, context.frameType); - if (!operation) { - Guard.raise("Unknown entity field operation: " + member.getJSON()); - } - member = Container.createMemberInfoExpression(operation); - result = Container.createFrameOperationExpression(exp, member, this._resolveFunctionArguments(args, operation.parameters)); - return result; - - case exp instanceof $data.Expressions.EntityExpression: - var operation = this.scopeContext.resolveTypeOperations(member.value, exp, context.frameType); - if (!operation) { - Guard.raise("Unknown entity function operation: " + member.getJSON()); - } - - member = Container.createMemberInfoExpression(operation); - result = Container.createEntityFunctionOperationExpression(exp, member, this._resolveFunctionArguments(args, operation.method.params)); - return result; - break; - case exp instanceof $data.Expressions.EntityContextExpression: - var operation = this.scopeContext.resolveContextOperations(member.value, exp, context.frameType); - if (!operation) { - Guard.raise("Unknown entity function operation: " + member.getJSON()); - } - - member = Container.createMemberInfoExpression(operation); - result = Container.createContextFunctionOperationExpression(exp, member, this._resolveFunctionArguments(args, operation.method.params)); - return result; - break; - default: - Guard.raise("VisitCall: Only fields can have operations: " + expression.getType().name); - //TODO we must not alter the visited tree - } - - }, - _resolveFunctionArguments: function (args, params) { - if (params) // remove current field poz - params = params.filter(function (p, i) { return p.name !== '@expression'; }); - - //objectArgs - if (args.length === 1 && args[0] instanceof $data.Expressions.ConstantExpression && typeof args[0].value === 'object' && args[0].value && params && params[0] && - args[0].value.constructor === $data.Object && params.some(function (param) { return param.name in args[0].value })) { - - return params.map(function (p) { - var type = p.type || p.dataType || args[0].type; - return new $data.Expressions.ConstantExpression(args[0].value[p.name], Container.resolveType(type), p.name); - }); - - } else { - return args.map(function (expr, i) { - if (expr instanceof $data.Expressions.ConstantExpression && params && params[i]) { - var type = params[i].type || params[i].dataType || expr.type; - return new $data.Expressions.ConstantExpression(expr.value, Container.resolveType(type), params[i].name); - } else { - return expr; - } - }); - } - }, - - VisitProperty: function (expression, context) { - /// - var exp = this.Visit(expression.expression, context); - var member = this.Visit(expression.member, context); - - //Guard.requireType("member", member, $data.Expressions.ConstantExpression); - Guard.requireType("member", member, $data.Expressions.ConstantExpression); - - function isPrimitiveType(memberDefinitionArg) { - - var t = memberDefinitionArg.dataType; - if (typeof t === 'function') { return false; } - - // suspicious code - /*switch (t) { - //TODO: implement this - }*/ - } - - switch (exp.expressionType) { - case $data.Expressions.EntityExpression: - var memberDefinition = exp.getMemberDefinition(member.value); - if (!memberDefinition) { - Guard.raise(new Exception("Unknown member: " + member.value, "MemberNotFound")); - } - //var storageMemberDefinition = - var storageField = memberDefinition.storageModel - .PhysicalType.memberDefinitions.getMember(memberDefinition.name); - var res; - var memberDefinitionExp; - switch (storageField.kind) { - case "property": - memberDefinitionExp = Container.createMemberInfoExpression(memberDefinition); - res = Container.createEntityFieldExpression(exp, memberDefinitionExp); - return res; - case "navProperty": - var assocInfo = memberDefinition.storageModel.Associations[memberDefinition.name]; - var setExpression = Container.createEntitySetExpression(exp, Container.createAssociationInfoExpression(assocInfo)); - if (assocInfo.ToMultiplicity !== "*") { - var ee = Container.createEntityExpression(setExpression, {}); - return ee; - }/* else { - context.lambdaParameters.push(setExpression); - }*/ - return setExpression; - case "complexProperty": - memberDefinitionExp = Container.createMemberInfoExpression(memberDefinition); - res = Container.createComplexTypeExpression(exp, memberDefinitionExp); - return res; - //TODO: missing default case - } - - //s/switch => property or navigationproperty - case $data.Expressions.ComplexTypeExpression: - var memDef = exp.getMemberDefinition(member.value); - if (!(memDef)) { - Guard.raise("Unknown member " + member.value + " on " + exp.entityType.name); - } - var memDefExp = Container.createMemberInfoExpression(memDef); - var result; - //TODO!!!! - if (Container.isPrimitiveType(Container.resolveType(memDef.dataType))) { - result = Container.createEntityFieldExpression(exp, memDefExp); - return result; - } - result = Container.createComplexTypeExpression(exp, memDefExp); - return result; - case $data.Expressions.QueryParameterExpression: - var value = expression.implementation(exp.value, member.value); - this.parameters[exp.index].name += "$" + member.value; - this.parameters[exp.index].value = value; - return Container.createQueryParameterExpression(exp.name + "$" + member.value, exp.index, value, Container.getTypeName(value)); - case $data.Expressions.EntityFieldExpression: - case $data.Expressions.EntityFieldOperationExpression: - var operation = this.scopeContext.resolveFieldOperation(member.value, exp, context.frameType); - if (!operation) { - Guard.raise("Unknown entity field operation: " + member.getJSON()); - } - member = Container.createMemberInfoExpression(operation); - result = Container.createEntityFieldOperationExpression(exp, member, []); - - return result; - default: - Guard.raise("Unknown expression type to handle: " + exp.expressionType.name); - } - } -});$C('$data.Expressions.ComplexTypeExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (source, selector) { - /// - /// - /// - /// - /// - /// - /// - /// - Guard.requireType("source", source, [$data.Expressions.EntityExpression, $data.Expressions.ComplexTypeExpression]); - Guard.requireType("selector", selector, [$data.Expressions.EntityExpression, $data.Expressions.MemberInfoExpression]); - this.source = source; - this.selector = selector; - var dt = source.entityType.getMemberDefinition(selector.memberName).dataType; - var t = Container.resolveType(dt); - this.entityType = t; - }, - - getMemberDefinition: function (name) { - return this.entityType.getMemberDefinition(name); - }, - - nodeType: { value: $data.Expressions.ExpressionType.Com } -}); - -$C('$data.Expressions.EntityContextExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (instance) { - /// - //Object.defineProperty(this, "instance", { value: instance, enumerable: false }); - this.instance = instance; - //this.storage_type = {}; - //this.typeName = this.type.name; - }, - instance: { enumerable: false }, - nodeType : { value: $data.Expressions.ExpressionType.EntityContext, enumerable: true } - -}); -$C('$data.Expressions.EntityExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (source, selector) { - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - Guard.requireValue("source", source); - Guard.requireValue("selector", selector); - if (!(source instanceof $data.Expressions.EntitySetExpression) && !(source instanceof $data.Expressions.ServiceOperationExpression)) { - Guard.raise("Only EntitySetExpressions can be the source for an EntityExpression"); - } - - this.source = source; - this.selector = selector; - - this.entityType = this.source.elementType; - this.storageModel = this.source.storageModel; - - Guard.requireValue("entityType", this.entityType); - Guard.requireValue("storageModel", this.storageModel); - - }, - - getMemberDefinition: function (name) { - var memdef = this.entityType.getMemberDefinition(name); - if (!(memdef)) { - Guard.raise(new Exception("Unknown member " + name + " on type "+ this.entityType.name, "MemberNotFound")); - }; - memdef.storageModel = this.storageModel; - return memdef; - }, - - nodeType: { value: $data.Expressions.ExpressionType.Entity } -});$C('$data.Expressions.EntityExpressionVisitor', null, null, { - - constructor: function () { - this.lambdaTypes = []; - }, - - canVisit: function (expression) { - return expression instanceof $data.Expressions.ExpressionNode; - }, - - Visit: function (expression, context) { - if (!this.canVisit(expression)) - return expression; - - var visitorName = "Visit" + expression.getType().name; - if (visitorName in this) { - var fn = this[visitorName]; - var result = fn.call(this, expression, context); - if (typeof result === 'undefined') { - return expression; - } - return result; - } - //console.log("unhandled expression type:" + expression.getType().name); - return expression; - }, - VisitToArrayExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - if (source !== expression.source) { - return Container.createToArrayExpression(source); - } - return expression; - }, - VisitForEachExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - if (source !== expression.source) { - return Container.createForEachExpression(source); - } - return expression; - }, - VisitMemberInfoExpression: function (expression, context) { - return expression; - }, - - VisitSingleExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - if (source !== expression.source) - return Container.createSingleExpression(source); - return expression; - }, - - VisitFirstExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - if (source !== expression.source) - return Container.createFirstExpression(source); - return expression; - }, - - VisitSomeExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - if (source !== expression.source) - return Container.createSomeExpression(source); - return expression; - }, - - VisitFindExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - if (source !== expression.source) - return Container.createFindExpression(source); - return expression; - }, - - VisitEveryExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - if (source !== expression.source) - return Container.createEveryExpression(source); - return expression; - }, - - VisitCountExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - if (source !== expression.source) - return Container.createCountExpression(source); - return expression; - }, - - VisitBatchDeleteExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - if (source !== expression.source) { - return Container.createBatchDeleteExpression(source); - } - return expression; - }, - - VisitObjectLiteralExpression: function (expression, context) { - var newValues = expression.members.map(function (ofe) { - return this.Visit(ofe, context); - }, this); - var equal = true; - for (var i = 0; i < expression.members.length; i++) { - equal = equal && (expression.members[i] === newValues[i]); - } - if (!equal) { - return Container.createObjectLiteralExpression(newValues); - } - return expression; - }, - VisitObjectFieldExpression: function (expression, context) { - var newExpression = this.Visit(expression.expression, context); - if (expression.expression !== newExpression) { - return Container.createObjectFieldExpression(expression.fieldName, newExpression); - } - return expression; - }, - VisitIncludeExpression: function (expression, context) { - var newExpression = this.Visit(expression.source, context); - if (newExpression !== expression.source) { - return Container.createIncludeExpression(newExpression, expression.selector); - } - return expression; - }, - - VisitUnaryExpression: function(expression, context) { - - /// - /// - var operand = this.Visit(expression.operand, context); - if (expression.operand !== operand) { - return Container.createUnaryExpression(operand, expression.operator, expression.nodeType, expression.resolution); - }; - return expression; - }, - - VisitSimpleBinaryExpression: function (expression, context) { - /// - /// - /// - // - var left = this.Visit(expression.left, context); - var right = this.Visit(expression.right, context); - if (left !== expression.left || right !== expression.right) { - return new $data.Expressions.SimpleBinaryExpression(left, right, expression.nodeType, - expression.operator, expression.type, expression.resolution); - } - return expression; - }, - - VisitEntityContextExpression: function (expression, context) { - return expression; - }, - - VisitCodeExpression: function (expression, context) { - /// - /// - /// - return expression; - }, - - VisitComplexTypeExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - var selector = this.Visit(expression.selector, context); - if (source !== expression.source || selector !== expression.selector) { - var result = Container.createComplexTypeExpression(source, selector); - return result; - } - return expression; - }, - - VisitEntityExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - var selector = this.Visit(expression.selector, context); - if (source !== expression.source || selector !== expression.selector) { - var result = Container.createEntityExpression(source, selector); - return result; - } - return expression; - }, - - VisitEntityFieldExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - var selector = this.Visit(expression.selector, context); - if (source !== expression.source || selector !== expression.selector) { - var result = Container.createEntityFieldExpression(source, selector); - return result; - } - return expression; - }, - - VisitEntityFieldOperationExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - var operation = this.Visit(expression.operation, context); - var parameters = expression.parameters.map(function (p) { - return this.Visit(p); - }, this); - var result = Container.createEntityFieldOperationExpression(source, operation, parameters); - return result; - }, - - VisitParametricQueryExpression: function (expression, context) { - var exp = this.Visit(expression.expression, context); - var args = expression.parameters.map(function (p) { - return this.Visit(p); - }, this); - var result = Container.createParametricQueryExpression(exp, args); - return result; - }, - - VisitEntitySetExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - var selector = this.Visit(expression.selector, context); - if (source !== expression.source || selector !== expression.selector) { - return Container.createEntitySetExpression(source, selector, expression.params, expression.instance); - } - return expression; - }, - - VisitInlineCountExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - var selector = this.Visit(expression.selector, context); - if (source !== expression.source || selector !== expression.selector) { - return Container.createInlineCountExpression(source, selector, expression.params, expression.instance); - } - return expression; - }, - - VisitFilterExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - var selector = this.Visit(expression.selector, context); - if (source !== expression.source || selector !== expression.selector) { - return Container.createFilterExpression(source, selector, expression.params, expression.instance); - } - return expression; - }, - - VisitProjectionExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - var selector = this.Visit(expression.selector, context); - if (source !== expression.source || selector !== expression.selector) { - var expr = Container.createProjectionExpression(source, selector, expression.params, expression.instance); - expr.projectionAs = expression.projectionAs; - return expr; - } - return expression; - }, - - VisitOrderExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - var selector = this.Visit(expression.selector, context); - if (source !== expression.source || selector !== expression.selector) { - return Container.createOrderExpression(source, selector, expression.nodeType); - } - return expression; - }, - VisitPagingExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - var amount = this.Visit(expression.amount, context); - if (source !== expression.source || amount !== expression.amount) { - return Container.createPagingExpression(source, amount, expression.nodeType); - } - return expression; - } -}); -$C('$data.Expressions.ExpressionMonitor', $data.Expressions.EntityExpressionVisitor, null, { - constructor: function (monitorDefinition) { - this.Visit = function (expression, context) { - - var result = expression; - var methodName; - if (this.canVisit(expression)) { - - //if (monitorDefinition.FilterExpressionNode) { - - //}; - - if (monitorDefinition.VisitExpressionNode) { - monitorDefinition.VisitExpressionNode.apply(monitorDefinition, arguments); - }; - - methodName = "Visit" + expression.getType().name; - if (methodName in monitorDefinition) { - result = monitorDefinition[methodName].apply(monitorDefinition, arguments); - } - } - - - //apply is about 3-4 times faster then call on webkit - - var args = arguments; - if (result !== expression) args = [result, context]; - result = $data.Expressions.EntityExpressionVisitor.prototype.Visit.apply(this, args); - - args = [result, context]; - - if (this.canVisit(result)) { - var expressionTypeName = result.getType().name; - if (monitorDefinition.MonitorExpressionNode) { - monitorDefinition.MonitorExpressionNode.apply(monitorDefinition, args); - } - methodName = "Monitor" + expressionTypeName; - if (methodName in monitorDefinition) { - monitorDefinition[methodName].apply(monitorDefinition, args); - } - - if (monitorDefinition.MutateExpressionNode) { - monitorDefinition.MutateExpressionNode.apply(monitorDefinition, args); - } - methodName = "Mutate" + expressionTypeName; - if (methodName in monitorDefinition) { - result = monitorDefinition[methodName].apply(monitorDefinition, args); - } - - } - return result; - }; - } -});$C('$data.Expressions.EntityFieldExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (source, selector) { - /// - /// - this.selector = selector; - this.source = source; - - - if (this.selector instanceof $data.Expressions.MemberInfoExpression || this.selector.name) { - this.memberName = this.selector.name; - } - }, - - nodeType: { value: $data.Expressions.ExpressionType.EntityField } -}); - -$C('$data.Expressions.EntityFieldOperationExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (source, operation, parameters) { - this.source = source; - this.operation = operation; - this.parameters = parameters; - }, - nodeType: { value: $data.Expressions.ExpressionType.EntityFieldOperation } - -});$C('$data.Expressions.EntitySetExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (source, selector, params, instance) { - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - Guard.requireType("source", source, - [$data.Expressions.EntityContextExpression, $data.Expressions.EntitySetExpression]); - Guard.requireType("selector", source, - [$data.Expressions.MemberInfoExpression, $data.Expressions.CodeExpression, $data.Expressions.ParametricQueryExpression]); - - this.source = source; - this.selector = selector; - this.params = params; - //Object.defineProperty(this, "instance", { value: instance, enumerable: false, writable: true }); - this.instance = instance; - - function findContext() { - //TODO: use source from function parameter and return a value at the end of the function - var r = source; - while (r) { - if (r instanceof $data.Expressions.EntityContextExpression) { - return r; - } - r = r.source; - } - } - - ///TODO!!! - this.storage_type = {}; - var c = findContext(); - switch (true) { - case this.source instanceof $data.Expressions.EntityContextExpression: - Guard.requireType("selector", selector, $data.Expressions.MemberInfoExpression); - this.elementType = selector.memberDefinition.elementType; - this.storageModel = c.instance._storageModel.getStorageModel(this.elementType); - break; - case this.source instanceof $data.Expressions.EntityExpression: - Guard.requireType("selector", selector, $data.Expressions.AssociationInfoExpression); - this.elementType = selector.associationInfo.ToType; - this.storageModel = c.instance._storageModel.getStorageModel(this.elementType); - break; - case this.source instanceof $data.Expressions.EntitySetExpression: - this.elementType = this.source.elementType; - this.storageModel = this.source.storageModel; - break; - case this.source instanceof $data.Expressions.ServiceOperationExpression: - this.elementType = this.source.elementType;//????????? - this.storageModel = this.source.storageModel; - break; - default: - Guard.raise("take and skip must be the last expressions in the chain!"); - //Guard.raise("Unknown source type for EntitySetExpression: " + this.getType().name); - break; - } - - // suspicious code - /*if (this.source instanceof $data.Expressions.EntitySetExpression) { - //TODO: missing operation - }*/ - //EntityTypeInfo - - }, - instance: { enumerable: false }, - nodeType: { value: $data.Expressions.ExpressionType.EntitySet, enumerable: true } -}); -$C('$data.Expressions.FrameOperationExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (source, operation, parameters) { - this.source = source; - this.operation = operation; - this.parameters = parameters; - }, - nodeType: { value: $data.Expressions.ExpressionType.FrameOperation } - -}); - -$C('$data.Expressions.EntityFunctionOperationExpression', $data.Expressions.FrameOperationExpression, null, { - nodeType: { value: $data.Expressions.ExpressionType.EntityFunctionOperation } -}); - -$C('$data.Expressions.ContextFunctionOperationExpression', $data.Expressions.FrameOperationExpression, null, { - nodeType: { value: $data.Expressions.ExpressionType.ContextFunctionOperation } -}); -$C('$data.Expressions.FilterExpression', $data.Expressions.EntitySetExpression, null, { - constructor: function (source, selector) { - /// - /// - /// - /// - /// - /// - /// - /// - this.resultType = $data.Array; - }, - nodeType: { value: $data.Expressions.ExpressionType.Filter, enumerable: true } -}); - -$C('$data.Expressions.InlineCountExpression', $data.Expressions.EntitySetExpression, null, { - constructor: function (source, selector) { - }, - nodeType: { value: $data.Expressions.ExpressionType.InlineCount, enumerable: true } -}); - -$C('$data.Expressions.FrameOperator', $data.Expressions.ExpressionNode, null, { - constructor: function () { - this.isTerminated = true; - } -}); - -$C('$data.Expressions.CountExpression', $data.Expressions.FrameOperator, null, { - constructor: function (source) { - /// - /// - /// - this.source = source; - this.resultType = $data.Integer; - }, - nodeType: { value: $data.Expressions.ExpressionType.Count, enumerable: true } -}); - -$C('$data.Expressions.SingleExpression', $data.Expressions.FrameOperator, null, { - constructor: function (source) { - /// - /// - /// - this.source = source; - this.resultType = $data.Object; - }, - nodeType: { value: $data.Expressions.ExpressionType.Single, enumerable: true } -}); - -$C('$data.Expressions.FindExpression', $data.Expressions.FrameOperator, null, { - constructor: function (source, params) { - /// - /// - /// - this.source = source; - this.params = params; - this.resultType = $data.Object; - }, - nodeType: { value: $data.Expressions.ExpressionType.Find, enumerable: true } -}); - -$C('$data.Expressions.FirstExpression', $data.Expressions.FrameOperator, null, { - constructor: function (source) { - /// - /// - /// - this.source = source; - this.resultType = $data.Object; - }, - nodeType: { value: $data.Expressions.ExpressionType.First, enumerable: true } -}); - -$C('$data.Expressions.ForEachExpression', $data.Expressions.FrameOperator, null, { - constructor: function (source) { - /// - /// - /// - this.source = source; - this.resultType = $data.Array; - }, - nodeType: { value: $data.Expressions.ExpressionType.ForEach, enumerable: true } -}); -$C('$data.Expressions.ToArrayExpression', $data.Expressions.FrameOperator, null, { - constructor: function (source) { - /// - /// - /// - this.source = source; - this.resultType = $data.Array; - }, - nodeType: { value: $data.Expressions.ExpressionType.ToArray, enumerable: true } -}); - -$C('$data.Expressions.SomeExpression', $data.Expressions.FrameOperator, null, { - constructor: function (source) { - /// - /// - /// - this.source = source; - this.resultType = $data.Object; - }, - nodeType: { value: $data.Expressions.ExpressionType.Some, enumerable: true } -}); - -$C('$data.Expressions.EveryExpression', $data.Expressions.FrameOperator, null, { - constructor: function (source) { - /// - /// - /// - this.source = source; - this.resultType = $data.Object; - }, - nodeType: { value: $data.Expressions.ExpressionType.Every, enumerable: true } -}); - -$C('$data.Expressions.BatchDeleteExpression', $data.Expressions.FrameOperator, null, { - constructor: function (source) { - /// - /// - /// - this.source = source; - this.resultType = $data.Integer; - }, - nodeType: { value: $data.Expressions.ExpressionType.BatchDelete, enumerable: true } -});$C('$data.Expressions.IncludeExpression', $data.Expressions.EntitySetExpression, null, { - constructor: function (source, selector) { - }, - nodeType: { value: $data.Expressions.ExpressionType.Include, writable: true }, - - toString: function (debug) { - //var result; - //result = debug ? this.type + " " : ""; - //result = result + this.name; - var result = "unimplemented"; - return result; - } -}, null); -$C('$data.Expressions.MemberInfoExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (memberDefinition) { - this.memberDefinition = memberDefinition; - this.memberName = memberDefinition.name; - }, - nodeType: { value: $data.Expressions.ExpressionType.MemberInfo, enumerable: true } - -});$C('$data.Expressions.OrderExpression', $data.Expressions.EntitySetExpression, null, { - constructor: function (source, expression, nType) { - /// - /// - //this.source = source; - //this.selector = expression; - this.nodeType = nType; - }, - nodeType: { value: $data.Expressions.ExpressionType.OrderBy, writable: true }, - - toString: function (debug) { - //var result; - //result = debug ? this.type + " " : ""; - //result = result + this.name; - var result = "unimplemented"; - return result; - } -}, null); -$C('$data.Expressions.ParametricQueryExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (expression, parameters) { - this.expression = expression; - this.parameters = parameters || []; - }, - nodeType: { value: $data.Expressions.ExpressionType.ParametricQuery, enumerable: true } -});$C('$data.Expressions.ProjectionExpression', $data.Expressions.EntitySetExpression, null, { - constructor: function (source, selector, params, instance) { - - }, - nodeType: { value: $data.Expressions.ExpressionType.Projection, enumerable: true } - -}); - - -$C('$data.Expressions.QueryExpressionCreator', $data.Expressions.EntityExpressionVisitor, null, { - constructor: function (scopeContext) { - /// - Guard.requireValue("scopeContext", scopeContext); - this.scopeContext = scopeContext; - }, - VisitEntitySetExpression: function (expression, context) { - if (expression.source instanceof $data.Expressions.EntityContextExpression) { - this.lambdaTypes.push(expression); - } - return expression; - }, - - VisitServiceOperationExpression: function (expression, context) { - if (expression.source instanceof $data.Expressions.EntityContextExpression) { - this.lambdaTypes.push(expression); - } - return expression; - }, - - VisitCodeExpression: function (expression, context) { - ///Converts the CodeExpression into an EntityExpression - /// - var source = expression.source.toString(); - var jsCodeTree = Container.createCodeParser(this.scopeContext).createExpression(source); - this.scopeContext.log({ event: "JSCodeExpression", data: jsCodeTree }); - - //TODO rename classes to reflex variable names - //TODO engage localValueResolver here - //var globalVariableResolver = Container.createGlobalContextProcessor(window); - var constantResolver = Container.createConstantValueResolver(expression.parameters, window, this.scopeContext); - var parameterProcessor = Container.createParameterResolverVisitor(); - - jsCodeTree = parameterProcessor.Visit(jsCodeTree, constantResolver); - - this.scopeContext.log({ event: "JSCodeExpressionResolved", data: jsCodeTree }); - var code2entity = Container.createCodeToEntityConverter(this.scopeContext); - - ///user provided query parameter object (specified as thisArg earlier) is passed in - var entityExpression = code2entity.Visit(jsCodeTree, { queryParameters: expression.parameters, lambdaParameters: this.lambdaTypes, frameType: context.frameType }); - - ///parameters are referenced, ordered and named, also collected in a flat list of name value pairs - var result = Container.createParametricQueryExpression(entityExpression, code2entity.parameters); - this.scopeContext.log({ event: "EntityExpression", data: entityExpression }); - - return result; - }, - - - VisitFilterExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - context = context || {}; - context.frameType = expression.getType(); - var selector = this.Visit(expression.selector, context); - if (source !== expression.source || selector !== expression.selector) { - return Container.createFilterExpression(source, selector, expression.params, expression.instance); - } - return expression; - }, - - VisitInlineCountExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - context = context || {}; - context.frameType = expression.getType(); - var selector = this.Visit(expression.selector, context); - if (source !== expression.source || selector !== expression.selector) { - return Container.createInlineCountExpression(source, selector, expression.params, expression.instance); - } - return expression; - }, - - VisitProjectionExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - context = context || {}; - context.frameType = expression.getType(); - var selector = this.Visit(expression.selector, context); - if (source !== expression.source || selector !== expression.selector) { - var expr = Container.createProjectionExpression(source, selector, expression.params, expression.instance); - expr.projectionAs = expression.projectionAs; - return expr; - } - return expression; - }, - - VisitOrderExpression: function (expression, context) { - var source = this.Visit(expression.source, context); - context = context || {}; - context.frameType = expression.getType(); - var selector = this.Visit(expression.selector, context); - if (source !== expression.source || selector !== expression.selector) { - return Container.createOrderExpression(source, selector, expression.nodeType); - } - return expression; - } -});$C('$data.Expressions.QueryParameterExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (name, index, value, type) { - this.name = name; - this.index = index; - this.value = value; - //TODO - this.type = Container.getTypeName(value); - }, - - nodeType: { value: $data.Expressions.ExpressionType.QueryParameter, writable: false } -});$C('$data.Expressions.RepresentationExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (kind) { - }, - - getMemberDefinition: function (name) { - return this.entityType.getMemberDefinition(name); - }, - - nodeType: { value: $data.Expressions.ExpressionType.Entity } -}); - -$C('$data.Expressions.ServiceOperationExpression', $data.Expressions.ExpressionNode, null, { - constructor: function (source, selector, params, cfg, boundItem) { - /// - /// - /// - /// - /// - /// - Guard.requireType("source", source, [$data.Expressions.EntityContextExpression]); - Guard.requireType("selector", source, [$data.Expressions.MemberInfoExpression]); - - this.source = source; - this.selector = selector - this.params = params - this.cfg = cfg; - this.boundItem = boundItem; - - function findContext() { - //TODO: use source from function parameter and return a value at the end of the function - var r = source; - while (r) { - if (r instanceof $data.Expressions.EntityContextExpression) { - return r; - } - r = r.source; - } - } - - var c = findContext(); - switch (true) { - case this.source instanceof $data.Expressions.EntityContextExpression: - this.elementType = cfg.elementType ? Container.resolveType(cfg.elementType) : (this.elementType ? Container.resolveType(cfg.returnType) : null); - this.storageModel = cfg.elementType ? c.instance._storageModel.getStorageModel(Container.resolveType(cfg.elementType)) : null; - break; - default: - Guard.raise("Unknown source type for EntitySetExpression: " + this.source.getType().name); - } - - }, - nodeType: { value: $data.Expressions.ExpressionType.ServiceOperation, enumerable: true } -});$C('$data.Expressions.ContinuationExpressionBuilder', $data.Expressions.EntityExpressionVisitor, null, { - constructor: function (mode) { - this.mode = mode; - }, - compile: function (query) { - - var findContext = { mode: "find", skipExists: false }; - this.Visit(query.expression, findContext); - - var result = { - skip: findContext.skipSize, - take: findContext.pageSize, - message: '' - } - - - if ('pageSize' in findContext) { - var expression; - var context = { mode: this.mode, pageSize: findContext.pageSize }; - - if (!findContext.skipExists && (findContext.pageSize)) { - context.append = true; - expression = this.Visit(query.expression, context); - - } else if (findContext.skipExists) { - expression = this.Visit(query.expression, context) - } - - if (!context.abort) { - result.expression = expression - } - else { - result.skip = (result.skip || 0) - result.take; - result.message = 'Invalid skip value!'; - } - }else{ - result.message = 'take expression not defined in the chain!'; - } - - return result; - }, - VisitPagingExpression: function (expression, context) { - - switch (context.mode) { - case 'find': - if (expression.nodeType === $data.Expressions.ExpressionType.Take) { - context.pageSize = expression.amount.value; - } else { - context.skipSize = expression.amount.value; - context.skipExists = true; - } - break; - case 'prev': - if (expression.nodeType === $data.Expressions.ExpressionType.Skip) { - var amount = expression.amount.value - context.pageSize; - context.abort = amount < 0 && expression.amount.value >= context.pageSize; - - var constExp = Container.createConstantExpression(Math.max(amount, 0), "number"); - return Container.createPagingExpression(expression.source, constExp, expression.nodeType); - } else if (context.append) { - //no skip expression, skip: 0, no prev - context.abort = true; - } - break; - case 'next': - if (expression.nodeType === $data.Expressions.ExpressionType.Skip) { - var amount = context.pageSize + expression.amount.value; - var constExp = Container.createConstantExpression(amount, "number"); - return Container.createPagingExpression(expression.source, constExp, expression.nodeType); - } else if (context.append) { - //no skip expression, skip: 0 - var constExp = Container.createConstantExpression(context.pageSize, "number"); - return Container.createPagingExpression(expression, constExp, $data.Expressions.ExpressionType.Skip); - } - break; - default: - } - - this.Visit(expression.source, context); - } -}); -$data.Class.define('$data.Validation.ValidationError', null, null, { - constructor: function (message, propertyDefinition, type) { - /// - /// - - this.Message = message; - this.PropertyDefinition = propertyDefinition; - this.Type = type; - }, - Type: { dataType: 'string' }, - Message: { dataType: "string" }, - PropertyDefinition: { dataType: $data.MemberDefinition } -}, null); - -$data.Class.define('$data.Validation.EntityValidationBase', null, null, { - - ValidateEntity: function (entity) { - /// - return []; - }, - - ValidateEntityField: function (entity, memberDefinition) { - /// - /// - return []; - }, - - getValidationValue: function (memberDefinition, validationName) { - Guard.raise("Pure class"); - }, - getValidationMessage: function (memberDefinition, validationName, defaultMessage) { - Guard.raise("Pure class"); - } - -}, null); - -$data.Validation = $data.Validation || {}; -$data.Validation.Entity = new $data.Validation.EntityValidationBase(); -$data.Class.define('$data.Validation.Defaults', null, null, null, { - validators: { - value: { - required: function (value, definedValue) { return !Object.isNullOrUndefined(value); }, - customValidator: function (value, definedValue) { return Object.isNullOrUndefined(value) || typeof definedValue == "function" ? definedValue(value) : true; }, - - minValue: function (value, definedValue) { return Object.isNullOrUndefined(value) || value >= definedValue; }, - maxValue: function (value, definedValue) { return Object.isNullOrUndefined(value) || value <= definedValue; }, - - minLength: function (value, definedValue) { return Object.isNullOrUndefined(value) || value.length >= definedValue; }, - maxLength: function (value, definedValue) { return Object.isNullOrUndefined(value) || value.length <= definedValue; }, - length: function (value, definedValue) { return Object.isNullOrUndefined(value) || value.length == definedValue; }, - regex: function (value, definedValue) { - return Object.isNullOrUndefined(value) || - value.match(typeof definedValue === 'string' - ? new RegExp((definedValue.indexOf('/') === 0 && definedValue.lastIndexOf('/') === (definedValue.length - 1)) ? definedValue.slice(1, -1) : definedValue) - : definedValue) - } - } - }, - - _getGroupValidations: function (validations) { - var validators = {}; - if (Array.isArray(validations)) { - for (var i = 0; i < validations.length; i++) { - var validator = validations[i]; - if (typeof this.validators[validator] === 'function') { - validators[validator] = this.validators[validator]; - } - } - } - - return validators; - } -}); - -$data.Class.define('$data.Validation.EntityValidation', $data.Validation.EntityValidationBase, null, { - - ValidateEntity: function (entity) { - /// - - var errors = []; - entity.getType().memberDefinitions.getPublicMappedProperties().forEach(function (memDef) { - errors = errors.concat(this.ValidateEntityField(entity, memDef, undefined, true)); - }, this); - return errors; - }, - ValidateEntityField: function (entity, memberDefinition, newValue, valueNotSet) { - /// - /// - var errors = []; - var resolvedType = Container.resolveType(memberDefinition.dataType); - var typeName = Container.resolveName(resolvedType); - var value = !valueNotSet ? newValue : entity[memberDefinition.name]; - - if (!memberDefinition.inverseProperty && resolvedType && typeof resolvedType.isAssignableTo === 'function' && resolvedType.isAssignableTo($data.Entity)) { - typeName = $data.Entity.fullName; - } - - this.fieldValidate(entity, memberDefinition, value, errors, typeName); - return errors; - }, - - getValidationValue: function (memberDefinition, validationName) { - var value; - if (memberDefinition[validationName] && memberDefinition[validationName].value) - value = memberDefinition[validationName].value; - else - value = memberDefinition[validationName]; - - if (this.convertableValidation[validationName]) { - var typeToConvert; - if (this.convertableValidation[validationName] === true) { - typeToConvert = memberDefinition.type; - } else { - typeToConvert = this.convertableValidation[validationName]; - } - - if (typeToConvert) - value = Container.convertTo(value, typeToConvert, memberDefinition.elementType); - } - - return value; - }, - getValidationMessage: function (memberDefinition, validationName, defaultMessage) { - var eMessage = defaultMessage; - if (typeof memberDefinition[validationName] == "object" && memberDefinition[validationName].message) - eMessage = memberDefinition[validationName].message; - else if (memberDefinition.errorMessage) - eMessage = memberDefinition.errorMessage; - - return eMessage; - }, - createValidationError: function (memberDefinition, validationName, defaultMessage) { - return new $data.Validation.ValidationError(this.getValidationMessage(memberDefinition, validationName, defaultMessage), memberDefinition, validationName); - }, - - convertableValidation: { - value: { - required: '$data.Boolean', - minValue: true, - maxValue: true, - minLength: '$data.Integer', - maxLength: '$data.Integer', - length: '$data.Integer' - } - - }, - supportedValidations: { - value: { - //'$data.Entity': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.ObjectID': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.Byte': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minValue', 'maxValue']), - '$data.SByte': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minValue', 'maxValue']), - '$data.Decimal': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minValue', 'maxValue']), - '$data.Float': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minValue', 'maxValue']), - '$data.Number': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minValue', 'maxValue']), - '$data.Int16': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minValue', 'maxValue']), - '$data.Integer': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minValue', 'maxValue']), - '$data.Int32': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minValue', 'maxValue']), - '$data.Int64': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minValue', 'maxValue']), - '$data.String': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minLength', 'maxLength', 'length', 'regex']), - '$data.Date': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minValue', 'maxValue']), - '$data.DateTimeOffset': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minValue', 'maxValue']), - '$data.Time': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minValue', 'maxValue']), - '$data.Boolean': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.Array': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'length']), - '$data.Object': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.Guid': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.Blob': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator', 'minLength', 'maxLength', 'length']), - '$data.GeographyPoint': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeographyLineString': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeographyPolygon': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeographyMultiPoint': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeographyMultiLineString': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeographyMultiPolygon': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeographyCollection': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeometryPoint': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeometryLineString': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeometryPolygon': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeometryMultiPoint': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeometryMultiLineString': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeometryMultiPolygon': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']), - '$data.GeometryCollection': $data.Validation.Defaults._getGroupValidations(['required', 'customValidator']) - } - }, - - fieldValidate: function (entity, memberDefinition, value, errors, validationTypeName) { - /// - /// - /// - /// - if (entity.entityState == $data.EntityState.Modified && entity.changedProperties && entity.changedProperties.indexOf(memberDefinition) < 0) - return; - - var validatonGroup = this.supportedValidations[validationTypeName]; - if (validatonGroup) { - var validations = Object.keys(validatonGroup); - validations.forEach(function (validation) { - if (memberDefinition[validation] && validatonGroup[validation] && !validatonGroup[validation].call(entity, value, this.getValidationValue(memberDefinition, validation))) - errors.push(this.createValidationError(memberDefinition, validation, 'Validation error!')); - }, this); - - if (validationTypeName === $data.Entity.fullName && value instanceof $data.Entity && !value.isValid()) { - errors.push(this.createValidationError(memberDefinition, 'ComplexProperty', 'Validation error!')); - } - } - } - -}, null); - -$data.Validation.Entity = new $data.Validation.EntityValidation(); - -$data.Class.define('$data.Notifications.ChangeDistributorBase', null, null, { - distributeData: function (collectorData) { - Guard.raise("Pure class"); - } -}, null); -$data.Class.define('$data.Notifications.ChangeCollectorBase', null, null, { - buildData: function (entityContextData) { - Guard.raise("Pure class"); - }, - processChangedData: function (entityData) { - if (this.Distrbutor && this.Distrbutor.distributeData) - this.Distrbutor.distributeData(this.buildData(entityData)); - }, - Distrbutor: { enumerable: false, dataType: $data.Notifications.ChangeDistributorBase, storeOnObject: true } -}, null); -$data.Class.define('$data.Notifications.ChangeDistributor', $data.Notifications.ChangeDistributorBase, null, { - constructor: function (broadcastUrl) { - this.broadcastUrl = broadcastUrl; - }, - distributeData: function (data) { - $data.ajax({ - url: this.broadcastUrl, - type: "POST", - data: 'data=' + JSON.stringify(data), - succes: this.success, - error: this.error - }); - }, - broadcastUrl: { dataType: "string" }, - success: function () { }, - error: function () { } -}, null); -$data.Class.define('$data.Notifications.ChangeCollector', $data.Notifications.ChangeCollectorBase, null, { - buildData: function (entities) { - var result = []; - entities.forEach(function (element) { - var resObj = { entityState: element.data.entityState, typeName: element.data.getType().name }; - var enumerableMemDefCollection = []; - - switch (element.data.entityState) { - case $data.EntityState.Added: - enumerableMemDefCollection = element.data.getType().memberDefinitions.getPublicMappedProperties(); - break; - case $data.EntityState.Modified: - enumerableMemDefCollection = element.data.changedProperties; - break; - case $data.EntityState.Deleted: - enumerableMemDefCollection = element.data.getType().memberDefinitions.getKeyProperties(); - break; - default: - break; - } - - enumerableMemDefCollection.forEach(function (memDef) { - resObj[memDef.name] = element.data[memDef.name]; - }); - - result.push(resObj); - }); - - return result; - } -}, null);$data.Class.define('$data.Transaction', null, null, { - constructor: function () { - this._objectId = (new Date()).getTime(); - $data.Trace.log("create: ", this._objectId); - - this.oncomplete = new $data.Event("oncomplete", this); - this.onerror = new $data.Event("onerror", this); - }, - abort: function () { - Guard.raise(new Exception('Not Implemented', 'Not Implemented', arguments)); - }, - - _objectId: { type: $data.Integer }, - transaction: { type: $data.Object }, - - oncomplete: { type: $data.Event }, - onerror: { type: $data.Event } -}, null);$data.Class.define('$data.Access', null, null, {}, { - isAuthorized: function(access, user, sets, callback){ - var pHandler = new $data.PromiseHandler(); - var clbWrapper = pHandler.createCallback(callback); - var pHandlerResult = pHandler.getPromise(); - - //clbWrapper.error('Authorization failed', 'Access authorization'); - clbWrapper.success(true); - - return pHandlerResult; - - /*var error; - - if (!access) error = 'Access undefined'; - if (typeof access !== 'number') error = 'Invalid access type'; - if (!user) user = {}; //error = 'User undefined'; - if (!user.roles) user.roles = {}; //error = 'User has no roles'; - if (!roles) roles = {}; //error = 'Roles undefined'; - if (!(roles instanceof Array || typeof roles === 'object')) error = 'Invald roles type'; - - var pHandler = new $data.PromiseHandler(); - var clbWrapper = pHandler.createCallback(callback); - var pHandlerResult = pHandler.getPromise(); - - if (error){ - clbWrapper.error(error, 'Access authorization'); - return pHandlerResult; - } - - if (user.roles instanceof Array){ - var r = {}; - for (var i = 0; i < user.roles.length; i++){ - if (typeof user.roles[i] === 'string') r[user.roles[i]] = true; - } - user.roles = r; - } - - if (roles instanceof Array){ - var r = {}; - for (var i = 0; i < roles.length; i++){ - if (typeof roles[i] === 'string') r[roles[i]] = true; - } - roles = r; - } - - var args = arguments; - var readyFn = function(result){ - if (result) clbWrapper.success(result); - else clbWrapper.error('Authorization failed', args); - }; - - var rolesKeys = Object.getOwnPropertyNames(roles); - var i = 0; - - var callbackFn = function(result){ - if (result) readyFn(result); - - if (typeof roles[rolesKeys[i]] === 'boolean' && roles[rolesKeys[i]]){ - if (user.roles[rolesKeys[i]]) readyFn(true); - else{ - i++; - if (i < rolesKeys.length) callbackFn(); - else readyFn(false); - } - }else if (typeof roles[rolesKeys[i]] === 'function'){ - var r = roles[rolesKeys[i]].call(user); - - if (typeof r === 'function') r.call(user, (i < rolesKeys.length ? callbackFn : readyFn)); - else{ - if (r) readyFn(true); - else{ - i++; - if (i < rolesKeys.length) callbackFn(); - else readyFn(false); - } - } - }else if (typeof roles[rolesKeys[i]] === 'number'){ - if (((typeof user.roles[rolesKeys[i]] === 'number' && (user.roles[rolesKeys[i]] & access)) || - (typeof user.roles[rolesKeys[i]] !== 'number' && user.roles[rolesKeys[i]])) && - (roles[rolesKeys[i]] & access)) user.roles[rolesKeys[i]] && readyFn(true); - else{ - i++; - if (i < rolesKeys.length) callbackFn(); - else readyFn(false); - } - } - }; - - callbackFn(); - - return pHandlerResult;*/ - }, - getAccessBitmaskFromPermission: function(p){ - var access = $data.Access.None; - - if (p.Create) access |= $data.Access.Create; - if (p.Read) access |= $data.Access.Read; - if (p.Update) access |= $data.Access.Update; - if (p.Delete) access |= $data.Access.Delete; - if (p.DeleteBatch) access |= $data.Access.DeleteBatch; - if (p.Execute) access |= $data.Access.Execute; - - return access; - }, - None: { value: 0 }, - Create: { value: 1 }, - Read: { value: 2 }, - Update: { value: 4 }, - Delete: { value: 8 }, - DeleteBatch: { value: 16 }, - Execute: { value: 32 } -}); -$data.Class.define('$data.Promise', null, null, { - always: function () { Guard.raise(new Exception('$data.Promise.always', 'Not implemented!')); }, - done: function () { Guard.raise(new Exception('$data.Promise.done', 'Not implemented!')); }, - fail: function () { Guard.raise(new Exception('$data.Promise.fail', 'Not implemented!')); }, - isRejected: function () { Guard.raise(new Exception('$data.Promise.isRejected', 'Not implemented!')); }, - isResolved: function () { Guard.raise(new Exception('$data.Promise.isResolved', 'Not implemented!')); }, - //notify: function () { Guard.raise(new Exception('$data.Promise.notify', 'Not implemented!')); }, - //notifyWith: function () { Guard.raise(new Exception('$data.Promise.notifyWith', 'Not implemented!')); }, - pipe: function () { Guard.raise(new Exception('$data.Promise.pipe', 'Not implemented!')); }, - progress: function () { Guard.raise(new Exception('$data.Promise.progress', 'Not implemented!')); }, - promise: function () { Guard.raise(new Exception('$data.Promise.promise', 'Not implemented!')); }, - //reject: function () { Guard.raise(new Exception('$data.Promise.reject', 'Not implemented!')); }, - //rejectWith: function () { Guard.raise(new Exception('$data.Promise.rejectWith', 'Not implemented!')); }, - //resolve: function () { Guard.raise(new Exception('$data.Promise.resolve', 'Not implemented!')); }, - //resolveWith: function () { Guard.raise(new Exception('$data.Promise.resolveWith', 'Not implemented!')); }, - state: function () { Guard.raise(new Exception('$data.Promise.state', 'Not implemented!')); }, - then: function () { Guard.raise(new Exception('$data.Promise.then', 'Not implemented!')); } -}, null); - -$data.Class.define('$data.PromiseHandlerBase', null, null, { - constructor: function () { }, - createCallback: function (callBack) { - callBack = $data.typeSystem.createCallbackSetting(callBack); - - return cbWrapper = { - success: callBack.success, - error: callBack.error, - notify: callBack.notify - }; - }, - getPromise: function () { - return new $data.Promise(); - } -}, null); - -$data.PromiseHandler = $data.PromiseHandlerBase; -var EventSubscriber = $data.Class.define("EventSubscriber", null, null, { - constructor: function (handler, state, thisArg) { - /// - /// event handler - /// - /// - /// - /// - /// - /// - /// custom state object - /// [i]this[/i] context for handler - /// - /// event handler - /// custom state object - /// [i]this[/i] context for handler - this.handler = handler; - this.state = state; - this.thisArg = thisArg; - }, - handler: {}, - state: {}, - thisArg: {} -}); - -$data.Event = Event = $data.Class.define("$data.Event", null, null, { - constructor: function (name, sender) { - ///The name of the event - ///The originator/sender of the event. [this] in handlers will be set to this - var subscriberList = null; - var parentObject = sender; - - function detachHandler(list, handler) { - /// - /// - list.forEach(function (item, index) { - if (item.handler == handler) { - list.splice(index, 1); - } - }); - } - - this.attach = function (handler, state, thisArg) { - /// - /// - /// - /// - /// - /// - /// - /// - /// - if (!subscriberList) { - subscriberList = []; - } - subscriberList.push(new EventSubscriber(handler, state, thisArg || sender)); - }; - this.detach = function (handler) { - detachHandler(subscriberList, handler); - }; - this.fire = function (eventData, snder) { - var snd = snder || sender || this; - //eventData.eventName = name; - /// - if (subscriberList) { - subscriberList.forEach(function (subscriber) { - /// - try { - subscriber.handler.call(subscriber.thisArg, snd, eventData, subscriber.state); - } catch(ex) { - console.log("unhandled exception in event handler. exception suppressed"); - console.dir(ex); - } - }); - } - }; - this.fireCancelAble = function (eventData, snder) { - var snd = snder || sender || this; - //eventData.eventName = name; - /// - var isValid = true; - if (subscriberList) { - subscriberList.forEach(function (subscriber) { - /// - try { - isValid = isValid && (subscriber.handler.call(subscriber.thisArg, snd, eventData, subscriber.state) === false ? false : true); - } catch (ex) { - console.log("unhandled exception in event handler. exception suppressed"); - console.dir(ex); - } - }); - } - return isValid; - }; - } -}); - - -var eventData = $data.Class.define("EventData", null, null, { - eventName: {} -}); - -var PropertyChangeEventData = $data.Class.define("PropertyChangeEventData", EventData, null, { - constructor: function (propertyName, oldValue, newValue) { - this.propertyName = propertyName; - this.oldValue = oldValue; - this.newValue = newValue; - }, - propertyName: {}, - oldValue: {}, - newValue: {} -}); - -var PropertyValidationEventData = $data.Class.define("PropertyValidationEventData", EventData, null, { - constructor: function (propertyName, oldValue, newValue, errors) { - this.propertyName = propertyName; - this.oldValue = oldValue; - this.newValue = newValue; - this.errors = errors; - this.cancel = false; - }, - propertyName: {}, - oldValue: {}, - newValue: {}, - errors: {}, - cancel: {} -}); - - - -$data.Entity = Entity = $data.Class.define("$data.Entity", null, null, { - constructor: function (initData, newInstanceOptions) { - /// - /// This class provide a light weight, object-relational interface between - /// your javascript code and database. - /// - /// - /// - /// initialization data - /// - /// var category = new $news.Types.Category({ Title: 'Tech' }); - /// $news.context.Categories.add(category); - /// - /// - /// - /// initialization data - /// - /// - /// - /// - /// Determines the current $data.Entity is validated. - /// array of $data.Validation.ValidationError - /// array of MemberDefinition - /// - /// array of MemberDefinition - - this.initData = {}; - var thisType = this.getType(); - if (thisType.__copyPropertiesToInstance) { - $data.typeSystem.writePropertyValues(this); - } - - var ctx = null; - this.context = ctx; - if ("setDefaultValues" in thisType) { - if (!newInstanceOptions || newInstanceOptions.setDefaultValues !== false) { - if (!initData || Object.keys(initData).length < 1) { - initData = thisType.setDefaultValues(initData); - } - } - } - - if (typeof initData === "object") { - var typeMemDefs = thisType.memberDefinitions; - var memDefNames = typeMemDefs.getPublicMappedPropertyNames(); - - for (var i in initData) { - if (memDefNames.indexOf(i) > -1) { - var memberDef = typeMemDefs.getMember(i); - var type = Container.resolveType(memberDef.type); - var value = initData[i]; - - if (memberDef.concurrencyMode === $data.ConcurrencyMode.Fixed) { - this.initData[i] = value; - } else { - if (newInstanceOptions && newInstanceOptions.converters) { - var converter = newInstanceOptions.converters[Container.resolveName(type)]; - if (converter) - value = converter(value); - } - - this.initData[i] = Container.convertTo(value, type, memberDef.elementType, newInstanceOptions); - } - } - } - - } - - if (newInstanceOptions && newInstanceOptions.entityBuilder) { - newInstanceOptions.entityBuilder(this, thisType.memberDefinitions.asArray(), thisType); - } - - this.changedProperties = undefined; - this.entityState = undefined; - - }, - toString: function () { - /// Returns a string that represents the current $data.Entity - /// - - return this.getType().fullName + "(" + (this.Id || this.Name || '') + ")" - }, - toJSON: function () { - /// Creates pure JSON object from $data.Entity. - /// JSON representation - - var result = {}; - var self = this; - this.getType().memberDefinitions.getPublicMappedProperties().forEach(function (memDef) { - if (self[memDef.name] instanceof Date && memDef.type && Container.resolveType(memDef.type) === $data.DateTimeOffset) { - result[memDef.name] = new $data.DateTimeOffset(self[memDef.name]); - } else { - result[memDef.name] = self[memDef.name]; - } - }); - return result; - }, - equals: function (entity) { - /// Determines whether the specified $data.Entity is equal to the current $data.Entity. - /// [b]true[/b] if the specified $data.Entity is equal to the current $data.Entity; otherwise, [b]false[/b]. - - if (entity.getType() !== this.getType()) { - return false; - } - var entityPk = this.getType().memberDefinitions.getKeyProperties(); - for (var i = 0; i < entityPk.length; i++) { - if (this[entityPk[i].name] != entity[entityPk[i].name]) { - return false; - } - } - return true; - }, - - propertyChanging: { - dataType: $data.Event, storeOnObject: true, monitorChanges: false, notMapped: true, enumerable: false, prototypeProperty: true, - get: function () { - if (!this._propertyChanging) - this._propertyChanging = new Event('propertyChanging', this); - - return this._propertyChanging; - }, - set: function (value) { this._propertyChanging = value; } - }, - - propertyChanged: { - dataType: $data.Event, storeOnObject: true, monitorChanges: false, notMapped: true, enumerable: false, prototypeProperty: true, - get: function () { - if (!this._propertyChanged) - this._propertyChanged = new Event('propertyChanged', this); - - return this._propertyChanged; - }, - set: function (value) { this._propertyChanged = value; } - }, - - propertyValidationError: { - dataType: $data.Event, storeOnObject: true, monitorChanges: false, notMapped: true, enumerable: false, prototypeProperty: true, - get: function () { - if (!this._propertyValidationError) - this._propertyValidationError = new Event('propertyValidationError', this); - - return this._propertyValidationError; - }, - set: function (value) { this._propertyValidationError = value; } - }, - - // protected - storeProperty: function (memberDefinition, value) { - /// - /// - - if (memberDefinition.concurrencyMode !== $data.ConcurrencyMode.Fixed) { - value = Container.convertTo(value, memberDefinition.type, memberDefinition.elementType); - } - - var eventData = null; - if (memberDefinition.monitorChanges != false && (this._propertyChanging || this._propertyChanged || "instancePropertyChanged" in this.constructor)) { - var origValue = this[memberDefinition.name]; - eventData = new PropertyChangeEventData(memberDefinition.name, origValue, value); - if (this._propertyChanging) - this.propertyChanging.fire(eventData); - } - - if (memberDefinition.monitorChanges != false && (this._propertyValidationError || "instancePropertyValidationError" in this.constructor)) { - var errors = $data.Validation.Entity.ValidateEntityField(this, memberDefinition, value); - if (errors.length > 0) { - var origValue = this[memberDefinition.name]; - var errorEventData = new PropertyValidationEventData(memberDefinition.name, origValue, value, errors); - - if (this._propertyValidationError) - this.propertyValidationError.fire(errorEventData); - if ("instancePropertyValidationError" in this.constructor) - this.constructor["instancePropertyValidationError"].fire(errorEventData, this); - - if (errorEventData.cancel == true) - return; - } - } - - if (memberDefinition.storeOnObject == true) { - //TODO refactor to Base.getBackingFieldName - var backingFieldName = "_" + memberDefinition.name; - this[backingFieldName] = value; - } else { - this.initData[memberDefinition.name] = value; - } - this.isValidated = false; - - if (memberDefinition.monitorChanges != false && this.entityState == $data.EntityState.Unchanged) - this.entityState = $data.EntityState.Modified; - - this._setPropertyChanged(memberDefinition); - - if (memberDefinition.monitorChanges != false) { - //if (!this.changedProperties) { - // this.changedProperties = []; - //} - - //if (!this.changedProperties.some(function (memDef) { return memDef.name == memberDefinition.name })) - // this.changedProperties.push(memberDefinition); - - if (this._propertyChanged) - this.propertyChanged.fire(eventData); - - //TODO mixin framework - if ("instancePropertyChanged" in this.constructor) { - this.constructor["instancePropertyChanged"].fire(eventData, this); - } - } - }, - _setPropertyChanged: function (memberDefinition) { - if (memberDefinition.monitorChanges != false) { - if (!this.changedProperties) { - this.changedProperties = []; - } - - if (!this.changedProperties.some(function (memDef) { return memDef.name == memberDefinition.name })) - this.changedProperties.push(memberDefinition); - } - }, - - // protected - retrieveProperty: function (memberDefinition) { - /// - - if (memberDefinition.storeOnObject == true) { - //TODO refactor to Base.getBackingFieldName - var backingFieldName = "_" + memberDefinition.name; - return this[backingFieldName]; - } else { - return this.initData[memberDefinition.name]; - } - }, - - // protected - getProperty: function (memberDefinition, callback, tran) { - /// Retrieve value of member - /// - /// - /// - /// - /// - /// - /// value associated for [i]memberDefinition[/i] - - callback = $data.typeSystem.createCallbackSetting(callback); - if (this[memberDefinition.name] != undefined) { - if (tran instanceof $data.Transaction) - callback.success(this[memberDefinition.name], tran); - else - callback.success(this[memberDefinition.name]); - return; - } - - var context = this.context; - if (!this.context) { - try { - var that = this; - var storeToken = this.storeToken || this.getType().storeToken; - if (storeToken && typeof storeToken.factory === 'function') { - var ctx = storeToken.factory(); - return ctx.onReady().then(function (context) { - return context.loadItemProperty(that, memberDefinition, callback); - }); - } - } catch (e) { } - - Guard.raise(new Exception('Entity not in context', 'Invalid operation')); - } else { - return context.loadItemProperty(this, memberDefinition, callback, tran); - } - }, - // protected - setProperty: function (memberDefinition, value, callback, tran) { - /// - /// - /// done - this[memberDefinition.name] = value; - - //callback = $data.typeSystem.createCallbackSetting(callback); - var pHandler = new $data.PromiseHandler(); - callback = pHandler.createCallback(callback); - callback.success(this[memberDefinition.name]); - return pHandler.getPromise(); - }, - - isValid: function () { - /// Determines the current $data.Entity is validated and valid. - /// - - if (!this.isValidated) { - this.ValidationErrors = $data.Validation.Entity.ValidateEntity(this); - this.isValidated = true; - } - return this.ValidationErrors.length == 0; - }, - isValidated: { dataType: "bool", storeOnObject: true, monitorChanges: false, notMapped: true, enumerable: false, value: false }, - ValidationErrors: { - dataType: Array, - elementType: $data.Validation.ValidationError, - storeOnObject: true, - monitorChanges: true, - notMapped: true, - enumerable: false - }, - - resetChanges: function () { - /// reset changes - - delete this._changedProperties; - }, - - changedProperties: { - dataType: Array, - elementType: window["MemberDefinition"], - storeOnObject: true, - monitorChanges: false, - notMapped: true, - enumerable: false - }, - - entityState: { dataType: "integer", storeOnObject: true, monitorChanges: false, notMapped: true, enumerable: false }, - /* - toJSON: function () { - if (this.context) { - var itemType = this.getType(); - var storageModel = this.context._storageModel[itemType.name]; - var o = new Object(); - for (var property in this) { - if (typeof this[property] !== "function") { - var excludedFields = storageModel.Associations.every(function (association) { - return association.FromPropertyName == property && (association.FromMultiplicity == "0..1" || association.FromMultiplicity == "1"); - }, this); - if (!excludedFields) { - o[property] = this[property]; - } - } - } - return o; - } - return this; - } */ - //, - - //onReady: function (callback) { - // this.__onReadyList = this.__onReadyList || []; - // this.__onReadyList.push(callback); - //}, - - remove: function () { - if ($data.ItemStore && 'EntityInstanceRemove' in $data.ItemStore) - return $data.ItemStore.EntityInstanceRemove.apply(this, arguments); - else - throw 'not implemented'; //todo - }, - save: function () { - if ($data.ItemStore && 'EntityInstanceSave' in $data.ItemStore) - return $data.ItemStore.EntityInstanceSave.apply(this, arguments); - else - throw 'not implemented'; //todo - }, - refresh: function () { - if ($data.ItemStore && 'EntityInstanceSave' in $data.ItemStore) - return $data.ItemStore.EntityInstanceRefresh.apply(this, arguments); - else - throw 'not implemented'; //todo - }, - storeToken: { type: Object, monitorChanges: false, notMapped: true, storeOnObject: true }, - - getFieldUrl: function (field) { - if (this.context) { - return this.context.getFieldUrl(this, field); - } else if (this.getType().storeToken && typeof this.getType().storeToken.factory === 'function') { - var context = this.getType().storeToken.factory(); - return context.getFieldUrl(this, field); - } else if (this.getType().storeToken){ - try { - var ctx = $data.ItemStore._getContextPromise('default', this.getType()); - if (ctx instanceof $data.EntityContext) { - return ctx.getFieldUrl(this, field); - } - } catch (e) { - } - } - return '#'; - } -}, -{ - //create get_[property] and set_[property] functions for properties - __setPropertyfunctions: { value: true, notMapped: true, enumerable: false, storeOnObject: true }, - //copy public properties to current instance - __copyPropertiesToInstance: { value: false, notMapped: true, enumerable: false, storeOnObject: true }, - - inheritedTypeProcessor: function (type) { - if ($data.ItemStore && 'EntityInheritedTypeProcessor' in $data.ItemStore) - $data.ItemStore.EntityInheritedTypeProcessor.apply(this, arguments); - - //default value setter method factory - type.defaultValues = {}; - - type.memberDefinitions.asArray().forEach(function (pd) { - if (pd.hasOwnProperty("defaultValue")) { - type.defaultValues[pd.name] = pd.defaultValue; - } - }); - - if (Object.keys(type.defaultValues).length > 0) { - type.setDefaultValues = function (initData, instance) { - initData = initData || {}; - var dv = type.defaultValues; - for (var n in dv) { - if (!(n in initData)) { - var value = dv[n]; - if ("function" === typeof value) { - initData[n] = dv[n](n, instance); - } else { - initData[n] = dv[n]; - } - } - } - return initData; - } - } - }, - - - //Type Events - addEventListener: function(eventName, fn) { - var delegateName = "on" + eventName; - if (!(delegateName in this)) { - this[delegateName] = new $data.Event(eventName, this); - } - this[delegateName].attach(fn); - }, - removeEventListener: function(eventName, fn) { - var delegateName = "on" + eventName; - if (!(delegateName in this)) { - return; - } - this[delegateName].detach(fn); - }, - raiseEvent: function(eventName, data) { - var delegateName = "on" + eventName; - if (!(delegateName in this)) { - return; - } - this[delegateName].fire(data); - }, - - getFieldNames: function () { - return this.memberDefinitions.getPublicMappedPropertyNames(); - }, - - 'from$data.Object': function (value, type, t, options) { - if (!Object.isNullOrUndefined(value)) { - var newInstanceOptions; - if (options && options.converters) { - newInstanceOptions = { - converters: options.converters - } - } - - return new this(value, newInstanceOptions); - } else { - return value; - } - } - -}); - - -$data.define = function (name, container, definition) { - if (container && !(container instanceof $data.ContainerClass)) { - definition = container; - container = undefined; - } - if (!definition) { - throw new Error("json object type is not supported yet"); - } - var _def = {}; - var hasKey = false; - var keyFields = []; - Object.keys(definition).forEach(function (fieldName) { - var propDef = definition[fieldName]; - if (typeof propDef === 'object' && ("type" in propDef || "get" in propDef || "set" in propDef)) { - - _def[fieldName] = propDef; - if (propDef.key) { - keyFields.push(propDef); - } - - if (("get" in propDef || "set" in propDef) && (!('notMapped' in propDef) || propDef.notMapped === true)) { - propDef.notMapped = true; - propDef.storeOnObject = true; - } - if ("get" in propDef && !("set" in propDef)) { - propDef.set = function () { }; - } else if ("set" in propDef && !("get" in propDef)) { - propDef.get = function () { }; - } - - } else { - _def[fieldName] = { type: propDef }; - } - }); - - if (keyFields.length < 1) { - var keyProp; - switch (true) { - case "id" in _def: - keyProp = "id"; - break; - case "Id" in _def: - keyProp = "Id" - break; - case "ID" in _def: - keyProp = "ID" - break; - } - if (keyProp) { - _def[keyProp].key = true; - var propTypeName = $data.Container.resolveName(_def[keyProp].type); - _def[keyProp].computed = true; - //if ("$data.Number" === propTypeName || "$data.Integer" === propTypeName) { - //} - } else { - _def.Id = { type: "int", key: true, computed: true } - } - } - - - var entityType = $data.Entity.extend(name, container, _def); - return entityType; -} -$data.implementation = function (name) { - return Container.resolveType(name); -}; - - - - -(function () { - - $data.defaults = $data.defaults || {}; - $data.defaults.defaultDatabaseName = 'JayDataDefault'; - -})(); - - -$data.Class.define('$data.StorageModel', null, null, { - constructor: function () { - ///User defined type - this.ComplexTypes = []; - this.Associations = []; - }, - LogicalType: {}, - LogicalTypeName: {}, - PhysicalType: {}, - PhysicalTypeName: {}, - EventHandlers: {}, - TableName: {}, - TableOptions: { value: undefined }, - ComplexTypes: {}, - Associations: {}, - ContextType: {}, - Roles: {} -}, null); -$data.Class.define('$data.Association', null, null, { - constructor: function (initParam) { - if (initParam) { - this.From = initParam.From; - this.FromType = initParam.FromType; - this.FromMultiplicity = initParam.FromMultiplicity; - this.FromPropertyName = initParam.FromPropertyName; - this.To = initParam.To; - this.ToType = initParam.ToType; - this.ToMultiplicity = initParam.ToMultiplicity; - this.ToPropertyName = initParam.ToPropertyName; - } - }, - From: {}, - FromType: {}, - FromMultiplicity: {}, - FromPropertyName: {}, - To: {}, - ToType: {}, - ToMultiplicity: {}, - ToPropertyName: {}, - ReferentialConstraint: {} -}, null); -$data.Class.define('$data.ComplexType', $data.Association, null, {}, null); - -$data.Class.define('$data.EntityContext', null, null, -{ - constructor: function (storageProviderCfg) { - /// Provides facilities for querying and working with entity data as objects. - ///Storage provider specific configuration object. - - if ($data.ItemStore && 'ContextRegister' in $data.ItemStore) - $data.ItemStore.ContextRegister.apply(this, arguments); - - if (storageProviderCfg.queryCache) - this.queryCache = storageProviderCfg.queryCache; - - if ("string" === typeof storageProviderCfg) { - if (0 === storageProviderCfg.indexOf("http")) { - storageProviderCfg = { - name: "oData", - oDataServiceHost: storageProviderCfg - } - } else { - storageProviderCfg = { - name: "local", - databaseName: storageProviderCfg - } - } - } - - if ("provider" in storageProviderCfg) { - storageProviderCfg.name = storageProviderCfg.provider; - } - - //Initialize properties - this.lazyLoad = false; - this.trackChanges = false; - this._entitySetReferences = {}; - this._storageModel = []; - - var ctx = this; - ctx._isOK = false; - - var origSuccessInitProvider = this._successInitProvider; - this._successInitProvider = function (errorOrContext) { - if (errorOrContext instanceof $data.EntityContext) { - origSuccessInitProvider(ctx); - } else { - origSuccessInitProvider(ctx, errorOrContext); - } - } - - this._storageModel.getStorageModel = function (typeName) { - var name = Container.resolveName(typeName); - return ctx._storageModel[name]; - }; - if (typeof storageProviderCfg.name === 'string') { - var tmp = storageProviderCfg.name; - storageProviderCfg.name = [tmp]; - } - var i = 0, providerType; - var providerList = [].concat(storageProviderCfg.name); - var callBack = $data.typeSystem.createCallbackSetting({ success: this._successInitProvider, error: this._successInitProvider }); - - this._initStorageModelSync(); - ctx._initializeEntitySets(ctx.getType()); - - $data.StorageProviderLoader.load(providerList, { - success: function (providerType) { - ctx.storageProvider = new providerType(storageProviderCfg, ctx); - ctx.storageProvider.setContext(ctx); - ctx.stateManager = new $data.EntityStateManager(ctx); - - var contextType = ctx.getType(); - if (providerType.name in contextType._storageModelCache) { - ctx._storageModel = contextType._storageModelCache[providerType.name]; - } else { - ctx._initializeStorageModel(); - contextType._storageModelCache[providerType.name] = ctx._storageModel; - } - - //ctx._initializeEntitySets(contextType); - if (storageProviderCfg && storageProviderCfg.user) Object.defineProperty(ctx, 'user', { value: storageProviderCfg.user, enumerable: true }); - if (storageProviderCfg && storageProviderCfg.checkPermission) Object.defineProperty(ctx, 'checkPermission', { value: storageProviderCfg.checkPermission, enumerable: true }); - - //ctx._isOK = false; - ctx._initializeStore(callBack); - }, - error: function () { - callBack.error('Provider fallback failed!'); - } - }); - - - - this.addEventListener = function (eventName, fn) { - var delegateName = "on" + eventName; - if (!(delegateName in this)) { - this[delegateName] = new $data.Event(eventName, this); - } - this[delegateName].attach(fn); - }; - - this.removeEventListener = function (eventName, fn) { - var delegateName = "on" + eventName; - if (!(delegateName in this)) { - return; - } - this[delegateName].detach(fn); - }; - - this.raiseEvent = function (eventName, data) { - var delegateName = "on" + eventName; - if (!(delegateName in this)) { - return; - } - this[delegateName].fire(data); - }; - - - this.ready = this.onReady({ - success: $data.defaultSuccessCallback, - error: function () { - if ($data.PromiseHandler !== $data.PromiseHandlerBase) { - $data.defaultErrorCallback.apply(this, arguments); - } else { - $data.Trace.error(arguments); - } - } - }); - }, - beginTransaction: function () { - var tables = null; - var callBack = null; - var isWrite = false; - - function readParam(value) { - if (Object.isNullOrUndefined(value)) return; - - if (typeof value === 'boolean') { - isWrite = value; - } else if (Array.isArray(value)) { - tables = value; - } else { - callBack = value; - } - } - - readParam(arguments[0]); - readParam(arguments[1]); - readParam(arguments[2]); - - var pHandler = new $data.PromiseHandler(); - callBack = pHandler.createCallback(callBack); - - //callBack = $data.typeSystem.createCallbackSetting(callBack); - this.storageProvider._beginTran(tables, isWrite, callBack); - - return pHandler.getPromise(); - }, - _isReturnTransaction: function (transaction) { - return transaction instanceof $data.Base || transaction === 'returnTransaction'; - }, - _applyTransaction: function (scope, cb, args, transaction, isReturnTransaction) { - if (isReturnTransaction === true) { - if (transaction instanceof $data.Transaction) { - Array.prototype.push.call(args, transaction); - cb.apply(scope, args); - } else { - this.beginTransaction(function (tran) { - Array.prototype.push.call(args, tran); - cb.apply(scope, args); - }); - } - } - else { - cb.apply(scope, args); - } - }, - - getDataType: function (dataType) { - // Obsolate - if (typeof dataType == "string") { - var memDef_dataType = this[dataType]; - if (memDef_dataType === undefined || memDef_dataType === null) { memDef_dataType = eval(dataType); } - return memDef_dataType; - } - return dataType; - }, - _initializeEntitySets: function (ctor) { - - for (var i = 0, l = this._storageModel.length; i < l; i++){ - var storageModel = this._storageModel[i]; - this[storageModel.ItemName] = new $data.EntitySet(storageModel.LogicalType, this, storageModel.ItemName, storageModel.EventHandlers, storageModel.Roles); - var sm = this[storageModel.ItemName]; - sm.name = storageModel.ItemName; - sm.tableName = storageModel.TableName; - sm.tableOptions = storageModel.TableOptions; - sm.eventHandlers = storageModel.EventHandlers; - this._entitySetReferences[storageModel.LogicalType.name] = sm; - - this._initializeActions(sm, ctor, ctor.getMemberDefinition(storageModel.ItemName)); - - } - - }, - _initializeStore: function (callBack) { - if (this.storageProvider) { - this.storageProvider.initializeStore(callBack); - } - }, - - _initStorageModelSync: function() { - var _memDefArray = this.getType().memberDefinitions.asArray(); - - - for (var i = 0; i < _memDefArray.length; i++) { - var item = _memDefArray[i]; - if ('dataType' in item) { - var itemResolvedDataType = Container.resolveType(item.dataType); - if (itemResolvedDataType && itemResolvedDataType.isAssignableTo && itemResolvedDataType.isAssignableTo($data.EntitySet)) { - var elementType = Container.resolveType(item.elementType); - var storageModel = new $data.StorageModel(); - storageModel.TableName = item.tableName || item.name; - storageModel.TableOptions = item.tableOptions; - storageModel.ItemName = item.name; - storageModel.LogicalType = elementType; - storageModel.LogicalTypeName = elementType.name; - storageModel.PhysicalTypeName = $data.EntityContext._convertLogicalTypeNameToPhysical(storageModel.LogicalTypeName); - storageModel.ContextType = this.getType(); - storageModel.Roles = item.roles; - if (item.indices) { - storageModel.indices = item.indices; - } - if (item.beforeCreate) { - if (!storageModel.EventHandlers) storageModel.EventHandlers = {}; - storageModel.EventHandlers.beforeCreate = item.beforeCreate; - } - if (item.beforeRead) { - if (!storageModel.EventHandlers) storageModel.EventHandlers = {}; - storageModel.EventHandlers.beforeRead = item.beforeRead; - } - if (item.beforeUpdate) { - if (!storageModel.EventHandlers) storageModel.EventHandlers = {}; - storageModel.EventHandlers.beforeUpdate = item.beforeUpdate; - } - if (item.beforeDelete) { - if (!storageModel.EventHandlers) storageModel.EventHandlers = {}; - storageModel.EventHandlers.beforeDelete = item.beforeDelete; - } - if (item.afterCreate) { - if (!storageModel.EventHandlers) storageModel.EventHandlers = {}; - storageModel.EventHandlers.afterCreate = item.afterCreate; - } - if (item.afterRead) { - if (!storageModel.EventHandlers) storageModel.EventHandlers = {}; - storageModel.EventHandlers.afterRead = item.afterRead; - } - if (item.afterUpdate) { - if (!storageModel.EventHandlers) storageModel.EventHandlers = {}; - storageModel.EventHandlers.afterUpdate = item.afterUpdate; - } - if (item.afterDelete) { - if (!storageModel.EventHandlers) storageModel.EventHandlers = {}; - storageModel.EventHandlers.afterDelete = item.afterDelete; - } - this._storageModel.push(storageModel); - var name = Container.resolveName(elementType); - this._storageModel[name] = storageModel; - } - } - } - - }, - _initializeStorageModel: function () { - - - var _memDefArray = this.getType().memberDefinitions.asArray(); - - - if (typeof intellisense !== 'undefined') - return; - - - for (var i = 0; i < this._storageModel.length; i++) { - var storageModel = this._storageModel[i]; - - ///Storage model item - var dbEntityInstanceDefinition = {}; - - storageModel.Associations = storageModel.Associations || []; - storageModel.ComplexTypes = storageModel.ComplexTypes || []; - for (var j = 0; j < storageModel.LogicalType.memberDefinitions.getPublicMappedProperties().length; j++) { - var memDef = storageModel.LogicalType.memberDefinitions.getPublicMappedProperties()[j]; - ///Member definition instance - - var memDefResolvedDataType = Container.resolveType(memDef.dataType); - - if ((this.storageProvider.supportedDataTypes.indexOf(memDefResolvedDataType) > -1) && Object.isNullOrUndefined(memDef.inverseProperty)) { - //copy member definition - var t = JSON.parse(JSON.stringify(memDef)); - //change datatype to resolved type - t.dataType = memDefResolvedDataType; - dbEntityInstanceDefinition[memDef.name] = t; - continue; - } - - this._buildDbType_navigationPropertyComplite(memDef, memDefResolvedDataType, storageModel); - - //var memDef_dataType = this.getDataType(memDef.dataType); - if ((memDefResolvedDataType === $data.Array || (memDefResolvedDataType.isAssignableTo && memDefResolvedDataType.isAssignableTo($data.EntitySet))) && - (memDef.inverseProperty && memDef.inverseProperty !== '$$unbound')) { - this._buildDbType_Collection_OneManyDefinition(dbEntityInstanceDefinition, storageModel, memDefResolvedDataType, memDef); - } else { - if (memDef.inverseProperty) { - if (memDef.inverseProperty === '$$unbound') { - //member definition is navigation but not back reference - if (memDefResolvedDataType === $data.Array) { - this._buildDbType_Collection_OneManyDefinition(dbEntityInstanceDefinition, storageModel, memDefResolvedDataType, memDef); - } else { - this._buildDbType_ElementType_OneManyDefinition(dbEntityInstanceDefinition, storageModel, memDefResolvedDataType, memDef); - } - } else { - //member definition is navigation property one..one or one..many case - var fields = memDefResolvedDataType.memberDefinitions.getMember(memDef.inverseProperty); - if (fields) { - if (fields.elementType) { - //member definition is one..many connection - var referealResolvedType = Container.resolveType(fields.elementType); - if (referealResolvedType === storageModel.LogicalType) { - this._buildDbType_ElementType_OneManyDefinition(dbEntityInstanceDefinition, storageModel, memDefResolvedDataType, memDef); - } else { - if (typeof intellisense === 'undefined') { - Guard.raise(new Exception('Inverse property not valid, refereed item element type not match: ' + storageModel.LogicalTypeName, ', property: ' + memDef.name)); - } - } - } else { - //member definition is one..one connection - this._buildDbType_ElementType_OneOneDefinition(dbEntityInstanceDefinition, storageModel, memDefResolvedDataType, memDef); - } - } else { - if (typeof intellisense === 'undefined') { - Guard.raise(new Exception('Inverse property not valid')); - } - } - } - } else { - //member definition is a complex type - this._buildDbType_addComplexTypePropertyDefinition(dbEntityInstanceDefinition, storageModel, memDefResolvedDataType, memDef); - } - } - } - this._buildDbType_modifyInstanceDefinition(dbEntityInstanceDefinition, storageModel, this); - var dbEntityClassDefinition = {}; - dbEntityClassDefinition.convertTo = this._buildDbType_generateConvertToFunction(storageModel, this); - this._buildDbType_modifyClassDefinition(dbEntityClassDefinition, storageModel, this); - - //create physical type - //TODO - storageModel.PhysicalType = $data.Class.define(storageModel.PhysicalTypeName, $data.Entity, storageModel.LogicalType.container, dbEntityInstanceDefinition, dbEntityClassDefinition); - } - }, - _initializeActions: function (es, ctor, esDef) { - if (esDef && esDef.actions) { - var actionKeys = Object.keys(esDef.actions); - for (var i = 0; i < actionKeys.length; i++) { - var actionName = actionKeys[i]; - var action = esDef.actions[actionName]; - if (typeof action === 'function') { - es[actionName] = action; - } else { - var actionDef = $data.MemberDefinition.translateDefinition(action, actionName, ctor); - if (actionDef instanceof $data.MemberDefinition && actionDef.kind === $data.MemberTypes.method) { - es[actionName] = actionDef.method; - } - } - } - } - }, - _buildDbType_navigationPropertyComplite: function (memDef, memDefResolvedDataType, storageModel) { - if (!memDef.inverseProperty) { - var refMemDefs = null; - if (memDefResolvedDataType === $data.Array || (memDefResolvedDataType.isAssignableTo && memDefResolvedDataType.isAssignableTo($data.EntitySet))) { - var refStorageModel = this._storageModel.getStorageModel(Container.resolveType(memDef.elementType)); - if (refStorageModel) { - refMemDefs = []; - var pubDefs = refStorageModel.LogicalType.memberDefinitions.getPublicMappedProperties(); - for (var i = 0; i < pubDefs.length; i++) { - var m = pubDefs[i]; - if ((m.inverseProperty == memDef.name) && (Container.resolveType(m.dataType) === Container.resolveType(storageModel.LogicalType))) - refMemDefs.push(m); - } - } - } else { - var refStorageModel = this._storageModel.getStorageModel(memDefResolvedDataType); - if (refStorageModel) { - refMemDefs = []; - var pubDefs = refStorageModel.LogicalType.memberDefinitions.getPublicMappedProperties(); - for (var i = 0; i < pubDefs.length; i++) { - var m = pubDefs[i]; - if (m.elementType && ((m.inverseProperty == memDef.name) && (Container.resolveType(m.elementType) === storageModel.LogicalType))) - refMemDefs.push(m); - else if ((m.inverseProperty == memDef.name) && (Container.resolveType(m.dataType) === storageModel.LogicalType)) - refMemDefs.push(m); - } - } - } - if (refMemDefs) { - if (refMemDefs.length > 1) { - if (typeof intellisense !== 'undefined') { - Guard.raise(new Exception('More than one inverse property refer to this member definition: ' + memDef.name + ', type: ' + Container.resolveName(storageModel.LogicalType))); - } - } - var refMemDef = refMemDefs.pop(); - if (refMemDef) { - memDef.inverseProperty = refMemDef.name; - } - } - } else { - var refStorageModel = null; - if (memDefResolvedDataType === $data.Array || (memDefResolvedDataType.isAssignableTo && memDefResolvedDataType.isAssignableTo($data.EntitySet))) { - refStorageModel = this._storageModel.getStorageModel(Container.resolveType(memDef.elementType)); - - } else { - refStorageModel = this._storageModel.getStorageModel(memDefResolvedDataType); - } - - var p = refStorageModel.LogicalType.memberDefinitions.getMember(memDef.inverseProperty); - if (p) { - if (p.inverseProperty) { - if (p.inverseProperty != memDef.name) { - if (typeof intellisense === 'undefined') { - Guard.raise(new Exception('Inverse property mismatch')); - } - } - } else { - p.inverseProperty = memDef.name; - } - } - - } - }, - _buildDbType_generateConvertToFunction: function (storageModel) { return function (instance) { return instance; }; }, - _buildDbType_modifyInstanceDefinition: function (instanceDefinition, storageModel) { return; }, - _buildDbType_modifyClassDefinition: function (classDefinition, storageModel) { return; }, - _buildDbType_addComplexTypePropertyDefinition: function (dbEntityInstanceDefinition, storageModel, memDef_dataType, memDef) { - this._addNavigationPropertyDefinition(dbEntityInstanceDefinition, memDef, memDef.name, $data.MemberTypes.complexProperty); - var complexType = this._createComplexElement(storageModel.LogicalType, "", memDef.name, memDef_dataType, "", ""); - storageModel.ComplexTypes[memDef.name] = complexType; - storageModel.ComplexTypes.push(complexType); - }, - _buildDbType_Collection_OneManyDefinition: function (dbEntityInstanceDefinition, storageModel, memDef_dataType, memDef) { - var refereedType = Container.resolveType(memDef.elementType); - if (refereedType === undefined || refereedType === null) { - if (typeof intellisense === 'undefined') { - Guard.raise(new Exception("Element type definition error", "Field definition", memDef)); - } - } - var refereedStorageModel = this._storageModel.getStorageModel(refereedType); - //var refereedStorageModel = this._storageModel.filter(function (s) { return s.LogicalType === refereedType; })[0]; - if (!refereedStorageModel) { - if (typeof intellisense === 'undefined') { - Guard.raise(new Exception("No EntitySet definition for the following element type", "Field definition", memDef)); - } - } - - this._addNavigationPropertyDefinition(dbEntityInstanceDefinition, memDef, memDef.name); - var associationType = memDef.inverseProperty === '$$unbound' ? '$$unbound' : '0..1'; - var association = this._addAssociationElement(storageModel.LogicalType, associationType, memDef.name, refereedStorageModel.LogicalType, "*", memDef.inverseProperty); - storageModel.Associations[memDef.name] = association; - storageModel.Associations.push(association); - }, - _buildDbType_ElementType_OneManyDefinition: function (dbEntityInstanceDefinition, storageModel, memDef_dataType, memDef) { - var refereedType = Container.resolveType(memDef.dataType); - if (refereedType === undefined || refereedType === null) { - if (typeof intellisense === 'undefined') { - Guard.raise(new Exception("Element type definition error", "Field definition", memDef)); - } - } - var refereedStorageModel = this._storageModel.getStorageModel(refereedType); - //var refereedStorageModel = this._storageModel.filter(function (s) { return s.LogicalType === refereedType; })[0]; - if (!refereedStorageModel) { - if (typeof intellisense === 'undefined') { - Guard.raise(new Exception("No EntitySet definition for the following element type", "Field definition", memDef)); - } - } - - this._addNavigationPropertyDefinition(dbEntityInstanceDefinition, memDef, memDef.name); - var associationType = memDef.inverseProperty === '$$unbound' ? '$$unbound' : '*'; - var association = this._addAssociationElement(storageModel.LogicalType, associationType, memDef.name, refereedStorageModel.LogicalType, "0..1", memDef.inverseProperty); - storageModel.Associations[memDef.name] = association; - storageModel.Associations.push(association); - }, - _buildDbType_ElementType_OneOneDefinition: function (dbEntityInstanceDefinition, storageModel, memDef_dataType, memDef) { - var refereedType = Container.resolveType(memDef.dataType); - if (refereedType === undefined || refereedType === null) { - if (typeof intellisense === 'undefined') { - Guard.raise(new Exception("Element type definition error", "Field definition", memDef)); - } - } - var refereedStorageModel = this._storageModel.getStorageModel(refereedType);; - //var refereedStorageModel = this._storageModel.filter(function (s) { return s.LogicalType === refereedType; })[0]; - if (!refereedStorageModel) { - if (typeof intellisense === 'undefined') { - Guard.raise(new Exception("No EntitySet definition following element type", "Field definition", memDef)); - } - } - - var refereedMemberDefinition = refereedStorageModel.LogicalType.memberDefinitions.getMember(memDef.inverseProperty); - if (!refereedMemberDefinition.required && !memDef.required) { if (typeof intellisense === 'undefined') { if (typeof intellisense === 'undefined') { Guard.raise(new Exception('In one to one connection, one side must required!', 'One to One connection', memDef)); } } } - - this._addNavigationPropertyDefinition(dbEntityInstanceDefinition, memDef, memDef.name); - - var association = this._addAssociationElement(storageModel.LogicalType, - memDef.required ? "0..1" : "1", - memDef.name, - refereedStorageModel.LogicalType, - memDef.required ? "1" : "0..1", - memDef.inverseProperty); - storageModel.Associations[memDef.name] = association; - storageModel.Associations.push(association); - }, - _addNavigationPropertyDefinition: function (definition, member, associationName, kind) { - var t = JSON.parse(JSON.stringify(member)); - t.dataType = $data.EntitySet; - t.notMapped = true; - t.kind = kind ? kind : $data.MemberTypes.navProperty; - t.association = associationName; - definition[member.name] = t; - }, - _addAssociationElement: function (fromType, fromMultiplicity, fromPropName, toType, toMultiplicity, toPropName) { - return new $data.Association({ - From: fromType.name, - FromType: fromType, - FromMultiplicity: fromMultiplicity, - FromPropertyName: fromPropName, - To: toType.name, - ToType: toType, - ToMultiplicity: toMultiplicity, - ReferentialConstraint: [], - ToPropertyName: toPropName - }); - }, - _createComplexElement: function (fromType, fromMultiplicity, fromPropName, toType, toMultiplicity, toPropName) { - return new $data.ComplexType({ - From: fromType.name, - FromType: fromType, - FromMultiplicity: fromMultiplicity, - FromPropertyName: fromPropName, - To: toType.name, - ToType: toType, - ToMultiplicity: toMultiplicity, - ReferentialConstraint: [], - ToPropertyName: toPropName - }); - }, - - _successInitProvider: function (context, error) { - if (context instanceof $data.EntityContext && context._isOK !== undefined) { - if (!error) { - context._isOK = true; - if (context.onReadyFunction) { - for (var i = 0; i < context.onReadyFunction.length; i++) { - context.onReadyFunction[i].success(context); - } - context.onReadyFunction = undefined; - } - } else { - context._isOK = error; - if (context.onReadyFunction) { - for (var i = 0; i < context.onReadyFunction.length; i++) { - context.onReadyFunction[i].error(error); - } - context.onReadyFunction = undefined; - } - } - } - }, - onReady: function (fn) { - /// - /// - /// Sets the callback function to be called when the initialization of the EntityContext has successfully finished. - /// - /// - /// Success callback - /// Current entityContext object - /// - /// - /// - /// - /// - /// Sets the callback functions to be called when the initialization of the EntityContext has finished. - /// - /// - /// Success and error callbacks definition. - /// Example: [code]{ success: function(db) { .. }, error: function() { .. } }[/code] - /// - /// - /// - var pHandler = new $data.PromiseHandler(); - var callBack = pHandler.createCallback(fn); - if (this._isOK === true) { - callBack.success(this); - } else if (this._isOK !== false) { - callBack.error(this._isOK); - } else { - this.onReadyFunction = this.onReadyFunction || []; - this.onReadyFunction.push(callBack); - } - - return pHandler.getPromise(); - }, - ready: { type: $data.Promise }, - getEntitySetFromElementType: function (elementType) { - /// - /// Gets the matching EntitySet for an element type. - /// - /// - /// - /// - /// Gets the matching EntitySet for an element type. - /// - /// - /// - var result = this._entitySetReferences[elementType]; - if (!result) { - try { - result = this._entitySetReferences[eval(elementType).name]; - } catch (ex) { } - } - return result; - }, - executeQuery: function (queryable, callBack, transaction) { - var query = new $data.Query(queryable.expression, queryable.defaultType, this); - query.transaction = transaction instanceof $data.Transaction ? transaction : undefined; - var returnTransaction = this._isReturnTransaction(transaction); - - callBack = $data.typeSystem.createCallbackSetting(callBack); - var that = this; - var clbWrapper = {}; - clbWrapper.success = function (query) { - if ($data.QueryCache && $data.QueryCache.isCacheable(that, query)) { - $data.QueryCache.addToCache(that, query); - } - - query.buildResultSet(that); - - if ($data.ItemStore && 'QueryResultModifier' in $data.ItemStore) - $data.ItemStore.QueryResultModifier.call(that, query); - - var successResult; - - if (query.expression.nodeType === $data.Expressions.ExpressionType.Single || - query.expression.nodeType === $data.Expressions.ExpressionType.Find || - query.expression.nodeType === $data.Expressions.ExpressionType.Count || - query.expression.nodeType === $data.Expressions.ExpressionType.BatchDelete || - query.expression.nodeType === $data.Expressions.ExpressionType.Some || - query.expression.nodeType === $data.Expressions.ExpressionType.Every) { - if (query.result.length !== 1) { - callBack.error(new Exception('result count failed')); - return; - } - - successResult = query.result[0]; - } else if (query.expression.nodeType === $data.Expressions.ExpressionType.First) { - if (query.result.length === 0) { - callBack.error(new Exception('result count failed')); - return; - } - - successResult = query.result[0]; - } else { - if (typeof query.__count === 'number' && query.result) - query.result.totalCount = query.__count; - - that.storageProvider._buildContinuationFunction(that, query); - - successResult = query.result; - } - - var readyFn = function () { - that._applyTransaction(callBack, callBack.success, [successResult], query.transaction, returnTransaction); - - /*if (returnTransaction === true) { - if (query.transaction) - callBack.success(successResult, query.transaction); - else { - that.beginTransaction(function (tran) { - callBack.success(successResult, tran); - }); - } - } - else - callBack.success(successResult);*/ - }; - - var i = 0; - var sets = query.getEntitySets(); - - var callbackFn = function () { - var es = sets[i]; - if (es.afterRead) { - i++; - var r = es.afterRead.call(this, successResult, sets, query); - if (typeof r === 'function') { - r.call(this, i < sets.length ? callbackFn : readyFn, successResult, sets, query); - } else { - if (i < sets.length) { - callbackFn(); - } else readyFn(); - } - } else readyFn(); - } - - if (sets.length) callbackFn(); - else readyFn(); - }; - - clbWrapper.error = function () { - if(returnTransaction) - callBack.error.apply(this, arguments); - else - callBack.error.apply(this, Array.prototype.filter.call(arguments, function (p) { return !(p instanceof $data.Transaction); })); - }; - var sets = query.getEntitySets(); - - var authorizedFn = function () { - var ex = true; - var wait = false; - var ctx = that; - - var readyFn = function (cancel) { - if (cancel === false) ex = false; - - if (ex) { - if (query.transaction) { - if ($data.QueryCache && $data.QueryCache.isInCache(that, query)) { - $data.QueryCache.executeQuery(that, query, clbWrapper); - } else { - ctx.storageProvider.executeQuery(query, clbWrapper); - } - } else { - ctx.beginTransaction(function (tran) { - query.transaction = tran; - if ($data.QueryCache && $data.QueryCache.isInCache(that, query)) { - $data.QueryCache.executeQuery(that, query, clbWrapper); - } else { - ctx.storageProvider.executeQuery(query, clbWrapper); - } - }); - } - } else { - query.rawDataList = []; - query.result = []; - clbWrapper.success(query); - } - }; - - var i = 0; - var callbackFn = function (cancel) { - if (cancel === false) ex = false; - - var es = sets[i]; - if (es.beforeRead) { - i++; - var r = es.beforeRead.call(this, sets, query); - if (typeof r === 'function') { - r.call(this, (i < sets.length && ex) ? callbackFn : readyFn, sets, query); - } else { - if (r === false) ex = false; - - if (i < sets.length && ex) { - callbackFn(); - } else readyFn(); - } - } else readyFn(); - }; - - if (sets.length) callbackFn(); - else readyFn(); - }; - - if (this.user && this.checkPermission) { - this.checkPermission(query.expression.nodeType === $data.Expressions.ExpressionType.BatchDelete ? $data.Access.DeleteBatch : $data.Access.Read, this.user, sets, { - success: authorizedFn, - error: clbWrapper.error - }); - } else authorizedFn(); - }, - saveChanges: function (callback, transaction) { - /// - /// - /// Saves the changes made to the context. - /// - /// - /// Success callback - /// Current entityContext object - /// - /// - /// - /// - /// - /// Saves the changes made to the context. - /// - /// - /// Success and error callbacks definition. - /// Example: [code]{ success: function(db) { .. }, error: function() { .. } }[/code] - /// - /// - /// - - if ($data.QueryCache) { - $data.QueryCache.reset(this); - } - - var changedEntities = []; - var trackedEntities = this.stateManager.trackedEntities; - var pHandler = new $data.PromiseHandler(); - var clbWrapper = pHandler.createCallback(callback); - var pHandlerResult = pHandler.getPromise(); - var returnTransaction = this._isReturnTransaction(transaction); - - var skipItems = []; - while (trackedEntities.length > 0) { - var additionalEntities = []; - //trackedEntities.forEach(function (entityCachedItem) { - for (var i = 0; i < trackedEntities.length; i++) { - var entityCachedItem = trackedEntities[i]; - - var sModel = this._storageModel.getStorageModel(entityCachedItem.data.getType()); - if (entityCachedItem.data.entityState == $data.EntityState.Unchanged) { - entityCachedItem.skipSave = true; - skipItems.push(entityCachedItem.data); - } else { - if (entityCachedItem.data.entityState == $data.EntityState.Modified) { - if (entityCachedItem.data.changedProperties) { - var changeStoredProperty = entityCachedItem.data.changedProperties.some(function (p) { - var pMemDef = sModel.PhysicalType.memberDefinitions.getMember(p.name); - if (pMemDef.kind == $data.MemberTypes.navProperty) { - var a = sModel.Associations[pMemDef.association]; - var multiplicity = a.FromMultiplicity + a.ToMultiplicity; - return ((multiplicity == '*0..1') || (multiplicity == '0..11')) - } - return true; - }); - if (!changeStoredProperty) { - entityCachedItem.skipSave = true; - skipItems.push(entityCachedItem.data); - } - } - } - } - - //type before events with items - this.processEntityTypeBeforeEventHandler(skipItems, entityCachedItem); - - var navigationProperties = []; - var smPhyMemDefs = sModel.PhysicalType.memberDefinitions.asArray(); - for (var ism = 0; ism < smPhyMemDefs.length; ism++) { - var p = smPhyMemDefs[ism]; - if (p.kind == $data.MemberTypes.navProperty) - navigationProperties.push(p); - } - //var navigationProperties = sModel.PhysicalType.memberDefinitions.asArray().filter(function (p) { return p.kind == $data.MemberTypes.navProperty; }); - //navigationProperties.forEach(function (navProp) { - for (var j = 0; j < navigationProperties.length; j++) { - var navProp = navigationProperties[j]; - - var association = sModel.Associations[navProp.name]; //eg.:"Profile" - var name = navProp.name; //eg.: "Profile" - var navPropertyName = association.ToPropertyName; //eg.: User - - var connectedDataList = [].concat(entityCachedItem.data[name]); - //connectedDataList.forEach(function (data) { - for (var k = 0; k < connectedDataList.length; k++) { - var data = connectedDataList[k]; - - if (data) { - var value = data[navPropertyName]; - var associationType = association.FromMultiplicity + association.ToMultiplicity; - if (association.FromMultiplicity === '$$unbound') { - if (data instanceof $data.Array) { - entityCachedItem.dependentOn = entityCachedItem.dependentOn || []; - //data.forEach(function (dataItem) { - for (var l = 0; l < data.length; l++) { - var dataItem = data[l]; - - if ((entityCachedItem.dependentOn.indexOf(data) < 0) && (data.skipSave !== true)) { - entityCachedItem.dependentOn.push(data); - } - } - //}, this); - } else { - entityCachedItem.dependentOn = entityCachedItem.dependentOn || []; - if ((entityCachedItem.dependentOn.indexOf(data) < 0) && (data.skipSave !== true)) { - entityCachedItem.dependentOn.push(data); - } - } - } else { - switch (associationType) { - case "*0..1": //Array - if (value) { - if (value instanceof Array) { - if (value.indexOf(entityCachedItem.data) == -1) { - value.push(entityCachedItem.data); - data.initData[navPropertyName] = value; - data._setPropertyChanged(association.ToType.getMemberDefinition(navPropertyName)); - } - } else { - if (typeof intellisense === 'undefined') { - Guard.raise("Item must be array or subtype of array"); - } - } - } else { - data.initData[navPropertyName] = [entityCachedItem.data]; - data._setPropertyChanged(association.ToType.getMemberDefinition(navPropertyName)); - } - break; - default: //Item - if (value) { - if (value !== entityCachedItem.data) { - if (typeof intellisense === 'undefined') { - Guard.raise("Integrity check error! Item assigned to another entity!"); - } - } - } else { - data.initData[navPropertyName] = entityCachedItem.data; //set back reference for live object - data._setPropertyChanged(association.ToType.getMemberDefinition(navPropertyName)); - } - break; - } - switch (associationType) { - case "*0..1": - case "0..11": - entityCachedItem.dependentOn = entityCachedItem.dependentOn || []; - if ((entityCachedItem.dependentOn.indexOf(data) < 0) && (data.skipSave !== true)) { - entityCachedItem.dependentOn.push(data); - } - break; - } - } - if (!data.entityState) { - if (data.storeToken === this.storeToken) { - data.entityState = $data.EntityState.Modified; - } else { - data.entityState = $data.EntityState.Added; - } - } - if (additionalEntities.indexOf(data) == -1) { - additionalEntities.push(data); - } - } - } - //}, this); - } - //}, this); - } - //}, this); - - //trackedEntities.forEach(function (entity) { - for (var i = 0; i < trackedEntities.length; i++) { - var entity = trackedEntities[i]; - - if (entity.skipSave !== true) { changedEntities.push(entity); } - } - //}); - - trackedEntities = []; - //additionalEntities.forEach(function (item) { - for (var i = 0; i < additionalEntities.length; i++) { - var item = additionalEntities[i]; - - if (!skipItems.some(function (entity) { return entity == item; })) { - if (!changedEntities.some(function (entity) { return entity.data == item; })) { - trackedEntities.push({ data: item, entitySet: this.getEntitySetFromElementType(item.getType().name) }); - } - } - } - //}, this); - } - - - //changedEntities.forEach(function (d) { - for (var j = 0; j < changedEntities.length; j++) { - var d = changedEntities[j]; - - if (d.dependentOn) { - var temp = []; - for (var i = 0; i < d.dependentOn.length; i++) { - if (skipItems.indexOf(d.dependentOn[i]) < 0) { - temp.push(d.dependentOn[i]); - } - } - d.dependentOn = temp; - } - } - //}); - skipItems = null; - var ctx = this; - if (changedEntities.length == 0) { - this.stateManager.trackedEntities.length = 0; - ctx._applyTransaction(clbWrapper, clbWrapper.success, [0], transaction, returnTransaction); - - /*if (returnTransaction) { - clbWrapper.success(0, transaction); - } else { - clbWrapper.success(0); - }*/ - return pHandlerResult; - } - - //validate entities - var errors = []; - //changedEntities.forEach(function (entity) { - for (var i = 0; i < changedEntities.length; i++) { - var entity = changedEntities[i]; - - if (entity.data.entityState === $data.EntityState.Added) { - //entity.data.getType().memberDefinitions.getPublicMappedProperties().forEach(function (memDef) { - for (var j = 0; j < entity.data.getType().memberDefinitions.getPublicMappedProperties().length; j++) { - var memDef = entity.data.getType().memberDefinitions.getPublicMappedProperties()[j]; - - var memDefType = Container.resolveType(memDef.type); - if (memDef.required && !memDef.computed && !entity.data[memDef.name] && !memDef.isDependentProperty) { - switch (memDefType) { - case $data.String: - case $data.Number: - case $data.Float: - case $data.Decimal: - case $data.Integer: - case $data.Int16: - case $data.Int32: - case $data.Int64: - case $data.Byte: - case $data.SByte: - case $data.Date: - case $data.Boolean: - entity.data[memDef.name] = Container.getDefault(memDef.dataType); - break; - default: - break; - } - } - } - //}, this); - } - if ((entity.data.entityState === $data.EntityState.Added || entity.data.entityState === $data.EntityState.Modified) - && !entity.data.isValid()) { - errors.push({ item: entity.data, errors: entity.data.ValidationErrors }); - } - } - //}); - if (errors.length > 0) { - clbWrapper.error(errors); - return pHandlerResult; - } - - var access = $data.Access.None; - - var eventData = {}; - var sets = []; - for (var i = 0; i < changedEntities.length; i++) { - var it = changedEntities[i]; - var n = it.entitySet.elementType.name; - if (sets.indexOf(it.entitySet) < 0) sets.push(it.entitySet); - var es = this._entitySetReferences[n]; - if (es.beforeCreate || es.beforeUpdate || es.beforeDelete || (this.user && this.checkPermission)) { - if (!eventData[n]) eventData[n] = {}; - - switch (it.data.entityState) { - case $data.EntityState.Added: - access |= $data.Access.Create; - if (es.beforeCreate) { - if (!eventData[n].createAll) eventData[n].createAll = []; - eventData[n].createAll.push(it); - } - break; - case $data.EntityState.Modified: - access |= $data.Access.Update; - if (es.beforeUpdate) { - if (!eventData[n].modifyAll) eventData[n].modifyAll = []; - eventData[n].modifyAll.push(it); - } - break; - case $data.EntityState.Deleted: - access |= $data.Access.Delete; - if (es.beforeDelete) { - if (!eventData[n].deleteAll) eventData[n].deleteAll = []; - eventData[n].deleteAll.push(it); - } - break; - } - } - } - - var readyFn = function (cancel) { - if (cancel === false) { - cancelEvent = 'async'; - changedEntities.length = 0; - } - - if (changedEntities.length) { - //console.log('changedEntities: ', changedEntities.map(function(it){ return it.data.initData; })); - - var innerCallback = { - success: function (tran) { - ctx._postProcessSavedItems(clbWrapper, changedEntities, tran, returnTransaction); - }, - error: function () { - //TODO remove trans from args; - if (returnTransaction) - clbWrapper.error.apply(this, arguments); - else - clbWrapper.error.apply(this, Array.prototype.filter.call(arguments, function (p) { return !(p instanceof $data.Transaction); })); - } - }; - - if (transaction instanceof $data.Transaction){ - ctx.storageProvider.saveChanges(innerCallback, changedEntities, transaction); - } else { - ctx.beginTransaction(true, function (tran) { - ctx.storageProvider.saveChanges(innerCallback, changedEntities, tran); - }); - } - } else if (cancelEvent) { - clbWrapper.error(new Exception('Cancelled event in ' + cancelEvent, 'CancelEvent')); - } else { - ctx._applyTransaction(clbWrapper, clbWrapper.success, [0], transaction, returnTransaction); - - /*if(returnTransaction) - clbWrapper.success(0, transaction); - else - clbWrapper.success(0);*/ - }; - - /*else if (cancelEvent) clbWrapper.error(new $data.Exception('saveChanges cancelled from event [' + cancelEvent + ']')); - else Guard.raise('No changed entities');*/ - }; - - var cancelEvent; - var ies = Object.getOwnPropertyNames(eventData); - var i = 0; - var cmd = ['beforeUpdate', 'beforeDelete', 'beforeCreate']; - var cmdAll = { - beforeCreate: 'createAll', - beforeDelete: 'deleteAll', - beforeUpdate: 'modifyAll' - }; - - var callbackFn = function (cancel) { - if (cancel === false) { - cancelEvent = 'async'; - changedEntities.length = 0; - - readyFn(cancel); - return; - } - - var es = ctx._entitySetReferences[ies[i]]; - var c = cmd.pop(); - var ed = eventData[ies[i]]; - var all = ed[cmdAll[c]]; - - if (all) { - var m = []; - for (var im = 0; im < all.length; im++) { - m.push(all[im].data); - } - //var m = all.map(function(it){ return it.data; }); - if (!cmd.length) { - cmd = ['beforeUpdate', 'beforeDelete', 'beforeCreate']; - i++; - } - - var r = es[c].call(ctx, m); - if (typeof r === 'function') { - r.call(ctx, (i < ies.length && !cancelEvent) ? callbackFn : readyFn, m); - } else if (r === false) { - cancelEvent = (es.name + '.' + c); - //all.forEach(function (it) { - for (var index = 0; index < all.length; index++) { - var it = all[index]; - - var ix = changedEntities.indexOf(it); - changedEntities.splice(ix, 1); - } - //}); - - readyFn(); - } else { - if (i < ies.length && !cancelEvent) callbackFn(); - else readyFn(); - } - } else { - if (!cmd.length) { - cmd = ['beforeUpdate', 'beforeDelete', 'beforeCreate']; - i++; - } - - if (i < ies.length && !cancelEvent) callbackFn(); - else readyFn(); - } - }; - - if (this.user && this.checkPermission) { - this.checkPermission(access, this.user, sets, { - success: function () { - if (i < ies.length) callbackFn(); - else readyFn(); - }, - error: clbWrapper.error - }); - } else { - if (i < ies.length) callbackFn(); - else readyFn(); - } - - return pHandlerResult; - }, - - processEntityTypeBeforeEventHandler: function (skipItems, entityCachedItem) { - if (!entityCachedItem.skipSave) { - var entity = entityCachedItem.data; - var entityType = entity.getType(); - var state = entity.entityState; - - switch (true) { - case state === $data.EntityState.Added && entityType.onbeforeCreate instanceof $data.Event: - if (entityType.onbeforeCreate.fireCancelAble(entity) === false) { - entityCachedItem.skipSave = true; - skipItems.push(entity); - } - break; - case state === $data.EntityState.Modified && entityType.onbeforeUpdate instanceof $data.Event: - if (entityType.onbeforeUpdate.fireCancelAble(entity) === false) { - entityCachedItem.skipSave = true; - skipItems.push(entity); - } - break; - case state === $data.EntityState.Deleted && entityType.onbeforeDelete instanceof $data.Event: - if (entityType.onbeforeDelete.fireCancelAble(entity) === false) { - entityCachedItem.skipSave = true; - skipItems.push(entity); - } - break; - default: - break; - } - } - }, - processEntityTypeAfterEventHandler: function (entityCachedItem) { - var entity = entityCachedItem.data; - var entityType = entity.getType(); - var state = entity.entityState; - - switch (true) { - case state === $data.EntityState.Added && entityType.onafterCreate instanceof $data.Event: - entityType.onafterCreate.fire(entity); - break; - case state === $data.EntityState.Modified && entityType.onafterUpdate instanceof $data.Event: - entityType.onafterUpdate.fire(entity); - break; - case state === $data.EntityState.Deleted && entityType.onafterDelete instanceof $data.Event: - entityType.onafterDelete.fire(entity); - break; - default: - break; - } - }, - - bulkInsert: function (entitySet, fields, datas, callback) { - var pHandler = new $data.PromiseHandler(); - callback = pHandler.createCallback(callback); - if (typeof entitySet === 'string') { - var currentEntitySet; - - for (var entitySetName in this._entitySetReferences) { - var actualEntitySet = this._entitySetReferences[entitySetName]; - if (actualEntitySet.tableName === entitySet) { - currentEntitySet = actualEntitySet; - break; - } - } - - if (!currentEntitySet) - currentEntitySet = this[entitySet]; - - entitySet = currentEntitySet; - } - if (entitySet) { - this.storageProvider.bulkInsert(entitySet, fields, datas, callback); - } else { - callback.error(new Exception('EntitySet not found')); - } - return pHandler.getPromise(); - }, - - prepareRequest: function () { }, - _postProcessSavedItems: function (callBack, changedEntities, transaction, returnTransaction) { - if (this.ChangeCollector && this.ChangeCollector instanceof $data.Notifications.ChangeCollectorBase) - this.ChangeCollector.processChangedData(changedEntities); - - var eventData = {}; - var ctx = this; - //changedEntities.forEach(function (entity) { - for (var i = 0; i < changedEntities.length; i++) { - var entity = changedEntities[i]; - - if (!entity.data.storeToken) - entity.data.storeToken = ctx.storeToken; - - //type after events with items - this.processEntityTypeAfterEventHandler(entity); - - var oes = entity.data.entityState; - - entity.data.entityState = $data.EntityState.Unchanged; - entity.data.changedProperties = []; - entity.physicalData = undefined; - - var n = entity.entitySet.elementType.name; - var es = ctx._entitySetReferences[n]; - - - var eventName = undefined; - switch (oes) { - case $data.EntityState.Added: - eventName = 'added'; - break; - case $data.EntityState.Deleted: - eventName = 'deleted'; - break; - case $data.EntityState.Modified: - eventName = 'updated'; - break; - } - if (eventName) { - this.raiseEvent(eventName, entity); - } - - if (es.afterCreate || es.afterUpdate || es.afterDelete) { - if (!eventData[n]) eventData[n] = {}; - - switch (oes) { - case $data.EntityState.Added: - if (es.afterCreate) { - if (!eventData[n].createAll) eventData[n].createAll = []; - eventData[n].createAll.push(entity); - } - break; - case $data.EntityState.Modified: - if (es.afterUpdate) { - if (!eventData[n].modifyAll) eventData[n].modifyAll = []; - eventData[n].modifyAll.push(entity); - } - break; - case $data.EntityState.Deleted: - if (es.afterDelete) { - if (!eventData[n].deleteAll) eventData[n].deleteAll = []; - eventData[n].deleteAll.push(entity); - } - break; - } - } - } - //}); - - var ies = Object.getOwnPropertyNames(eventData); - var i = 0; - var ctx = this; - var cmd = ['afterUpdate', 'afterDelete', 'afterCreate']; - var cmdAll = { - afterCreate: 'createAll', - afterDelete: 'deleteAll', - afterUpdate: 'modifyAll' - }; - - var readyFn = function () { - if (!ctx.trackChanges) { - ctx.stateManager.reset(); - } - - ctx._applyTransaction(callBack, callBack.success, [changedEntities.length], transaction, returnTransaction); - - /*if (returnTransaction) - callBack.success(changedEntities.length, transaction); - else - callBack.success(changedEntities.length);*/ - }; - - var callbackFn = function () { - var es = ctx._entitySetReferences[ies[i]]; - var c = cmd.pop(); - var ed = eventData[ies[i]]; - var all = ed[cmdAll[c]]; - if (all) { - var m = []; - for (var im = 0; im < all.length; im++) { - m.push(all[im].data); - } - //var m = all.map(function(it){ return it.data; }); - if (!cmd.length) { - cmd = ['afterUpdate', 'afterDelete', 'afterCreate']; - i++; - } - - var r = es[c].call(ctx, m); - if (typeof r === 'function') { - r.call(ctx, i < ies.length ? callbackFn : readyFn, m); - } else { - if (i < ies.length) callbackFn(); - else readyFn(); - } - } else { - if (!cmd.length) { - cmd = ['afterUpdate', 'afterDelete', 'afterCreate']; - i++; - } - - if (i < ies.length) callbackFn(); - else readyFn(); - } - }; - - if (i < ies.length) callbackFn(); - else readyFn(); - }, - forEachEntitySet: function (fn, ctx) { - /// - /// Iterates over the entity sets' of current EntityContext. - /// - /// - /// - /// - /// 'this' argument for the 'fn' function. - for (var entitySetName in this._entitySetReferences) { - var actualEntitySet = this._entitySetReferences[entitySetName]; - fn.call(ctx, actualEntitySet); - } - }, - - loadItemProperty: function (entity, property, callback, transaction) { - /// - /// Loads a property of the entity through the storage provider. - /// Entity object - /// Property name - /// - /// C allback function - /// - /// - /// - /// - /// - /// Loads a property of the entity through the storage provider. - /// Entity object - /// Property name - /// - /// Success and error callbacks definition. - /// Example: [code]{ success: function(db) { .. }, error: function() { .. } }[/code] - /// - /// - /// - /// - /// Loads a property of the entity through the storage provider. - /// Entity object - /// Property definition - /// - /// Callback function - /// - /// - /// - /// - /// - /// Loads a property of the entity through the storage provider. - /// Entity object - /// Property definition - /// - /// Success and error callbacks definition. - /// Example: [code]{ success: function(db) { .. }, error: function() { .. } }[/code] - /// - /// - /// - Guard.requireType('entity', entity, $data.Entity); - - var memberDefinition = typeof property === 'string' ? entity.getType().memberDefinitions.getMember(property) : property; - var returnTransaction = this._isReturnTransaction(transaction); - - if (entity[memberDefinition.name] != undefined) { - - var pHandler = new $data.PromiseHandler(); - callBack = pHandler.createCallback(callback); - this._applyTransaction(callback, callback.success, [entity[memberDefinition.name]], transaction, returnTransaction); - /*if (returnTransaction) - callback.success(entity[memberDefinition.name], transaction); - else - callback.success(entity[memberDefinition.name]);*/ - - return pHandler.getPromise(); - } - - var isSingleSide = true; - var storageModel = this._storageModel.getStorageModel(entity.getType().fullName); - var elementType = Container.resolveType(memberDefinition.dataType); - if (elementType === $data.Array || (elementType.isAssignableTo && elementType.isAssignableTo($data.EntitySet))) { - elementType = Container.resolveType(memberDefinition.elementType); - - isSingleSide = false; - - } else { - var associations; - for (var i = 0; i < storageModel.Associations.length; i++) { - var assoc = storageModel.Associations[i]; - if (assoc.FromPropertyName == memberDefinition.name) { - associations = assoc; - break; - } - } - //var associations = storageModel.Associations.filter(function (assoc) { return assoc.FromPropertyName == memberDefinition.name; })[0]; - if (associations && associations.FromMultiplicity === "0..1" && associations.ToMultiplicity === "1") - isSingleSide = false; - } - - var keyProp = storageModel.LogicalType.memberDefinitions.getKeyProperties(); - if (isSingleSide === true) { - //singleSide - - var filterFunc = "function (e) { return"; - var filterParams = {}; - //storageModel.LogicalType.memberDefinitions.getKeyProperties().forEach(function (memDefKey, index) { - for (var index = 0; index < keyProp.length; index++) { - var memDefKey = keyProp[index]; - - if (index > 0) - filterFunc += ' &&'; - filterFunc += " e." + memDefKey.name + " == this.key" + index; - filterParams['key' + index] = entity[memDefKey.name]; - } - //}); - filterFunc += "; }" - - var entitySet = this.getEntitySetFromElementType(entity.getType()); - return entitySet - .map('function (e) { return e.' + memberDefinition.name + ' }') - .single(filterFunc, filterParams, callback, transaction); - } else { - //multipleSide - - var filterFunc = "function (e) { return" - var filterParams = {}; - //storageModel.LogicalType.memberDefinitions.getKeyProperties().forEach(function (memDefKey, index) { - for (var index = 0; index < keyProp.length; index++) { - var memDefKey = keyProp[index]; - - if (index > 0) - filterFunc += ' &&'; - filterFunc += " e." + memberDefinition.inverseProperty + "." + memDefKey.name + " == this.key" + index; - filterParams['key' + index] = entity[memDefKey.name]; - } - //}); - filterFunc += "; }" - - var entitySet = this.getEntitySetFromElementType(elementType); - return entitySet - .filter(filterFunc, filterParams) - .toArray(callback, transaction); - } - - }, - - getTraceString: function (queryable) { - /// - /// Returns a trace string. Used for debugging purposes! - /// - /// - /// Trace string - var query = new $data.Query(queryable.expression, queryable.defaultType, this); - return this.storageProvider.getTraceString(query); - }, - log: function (logInfo) { - //noop as do nothing - }, - - resolveBinaryOperator: function (operator, expression, frameType) { - return this.storageProvider.resolveBinaryOperator(operator, expression, frameType); - }, - resolveUnaryOperator: function (operator, expression, frameType) { - return this.storageProvider.resolveUnaryOperator(operator, expression, frameType); - }, - resolveFieldOperation: function (operation, expression, frameType) { - return this.storageProvider.resolveFieldOperation(operation, expression, frameType); - }, - resolveSetOperations: function (operation, expression, frameType) { - return this.storageProvider.resolveSetOperations(operation, expression, frameType); - }, - resolveTypeOperations: function (operation, expression, frameType) { - return this.storageProvider.resolveTypeOperations(operation, expression, frameType); - }, - resolveContextOperations: function (operation, expression, frameType) { - return this.storageProvider.resolveContextOperations(operation, expression, frameType); - }, - - _generateServiceOperationQueryable: function (functionName, returnEntitySet, arg, parameters) { - if (typeof console !== 'undefined' && console.log) - console.log('Obsolate: _generateServiceOperationQueryable, $data.EntityContext'); - - var params = []; - for (var i = 0; i < parameters.length; i++) { - var obj = {}; - obj[parameters[i]] = Container.resolveType(Container.getTypeName(arg[i])); - params.push(obj); - } - - var tempOperation = $data.EntityContext.generateServiceOperation({ serviceName: functionName, returnType: $data.Queryable, elementType: this[returnEntitySet].elementType, params: params }); - return tempOperation.apply(this, arg); - }, - attach: function (entity, mode) { - /// - /// Attaches an entity to its matching entity set. - /// - /// - /// Returns the attached entity. - - if (entity instanceof $data.EntityWrapper) { - entity = entity.getEntity(); - } - var entitySet = this.getEntitySetFromElementType(entity.getType()); - return entitySet.attach(entity, mode); - }, - attachOrGet: function (entity, mode) { - /// - /// Attaches an entity to its matching entity set, or returns if it's already attached. - /// - /// - /// Returns the entity. - - if (entity instanceof $data.EntityWrapper) { - entity = entity.getEntity(); - } - var entitySet = this.getEntitySetFromElementType(entity.getType()); - return entitySet.attachOrGet(entity, mode); - }, - - addMany: function (entities) { - /// - /// Adds several entities to their matching entity set. - /// - /// - /// Returns the added entities. - var self = this; - entities.forEach(function (entity) { - self.add(entity); - }); - return entities; - }, - - add: function (entity) { - /// - /// Adds a new entity to its matching entity set. - /// - /// - /// Returns the added entity. - - if (entity instanceof $data.EntityWrapper) { - entity = entity.getEntity(); - } - var entitySet = this.getEntitySetFromElementType(entity.getType()); - return entitySet.add(entity); - }, - remove: function (entity) { - /// - /// Removes an entity from its matching entity set. - /// - /// - /// Returns the removed entity. - - if (entity instanceof $data.EntityWrapper) { - entity = entity.getEntity(); - } - var entitySet = this.getEntitySetFromElementType(entity.getType()); - return entitySet.remove(entity); - }, - storeToken: { type: Object }, - - getFieldUrl: function (entity, member, collection) { - try { - var entitySet = typeof collection === 'string' ? this[collection] : collection; - var fieldName = typeof member === 'string' ? member : member.name; - if (entity instanceof $data.Entity) { - entitySet = this.getEntitySetFromElementType(entity.getType()); - } else if (!Object.isNullOrUndefined(entity) && entity.constructor !== $data.Object) { //just a single key - var keyDef = entitySet.elementType.memberDefinitions.getKeyProperties()[0]; - var key = {}; - key[keyDef.name] = entity; - entity = key; - } - - //key object - if (!(entity instanceof $data.Entity)) { - entity = new entitySet.elementType(entity); - } - - return this.storageProvider.getFieldUrl(entity, fieldName, entitySet); - } catch (e) {} - return '#'; - } -}, { - inheritedTypeProcessor: function(type) { - if (type.resolveForwardDeclarations) { - type.resolveForwardDeclarations(); - } - }, - generateServiceOperation: function (cfg) { - - var fn; - if (cfg.serviceMethod) { - var returnType = cfg.returnType ? Container.resolveType(cfg.returnType) : {}; - if (returnType.isAssignableTo && returnType.isAssignableTo($data.Queryable)) { - fn = cfg.serviceMethod; - } else { - fn = function () { - var lastParam = arguments[arguments.length - 1]; - - var pHandler = new $data.PromiseHandler(); - var cbWrapper; - - var args = arguments; - if (typeof lastParam === 'function') { - cbWrapper = pHandler.createCallback(lastParam); - arguments[arguments.length - 1] = cbWrapper; - } else { - cbWrapper = pHandler.createCallback(); - arguments.push(cbWrapper); - } - - try { - var result = cfg.serviceMethod.apply(this, arguments); - if (result !== undefined) - cbWrapper.success(result); - } catch (e) { - cbWrapper.error(e); - } - - return pHandler.getPromise(); - } - } - - } else { - fn = function () { - var context = this; - - var boundItem; - if (this instanceof $data.Entity) { - if (!cfg.method) { - cfg.method = 'POST'; - } - - if (this.context) { - context = this.context; - } else { - Guard.raise('entity not attached into context'); - return; - } - - boundItem = { - data: this, - entitySet: context.getEntitySetFromElementType(this.getType()) - }; - } - - var virtualEntitySet = cfg.elementType ? context.getEntitySetFromElementType(Container.resolveType(cfg.elementType)) : null; - - var paramConstExpression = null; - if (cfg.params) { - paramConstExpression = []; - for (var i = 0; i < cfg.params.length; i++) { - //TODO: check params type - for (var name in cfg.params[i]) { - paramConstExpression.push(Container.createConstantExpression(arguments[i], Container.resolveType(cfg.params[i][name]), name)); - } - } - } - - var ec = Container.createEntityContextExpression(context); - var memberdef = (boundItem ? boundItem.data : context).getType().getMemberDefinition(cfg.serviceName); - var es = Container.createServiceOperationExpression(ec, - Container.createMemberInfoExpression(memberdef), - paramConstExpression, - cfg, - boundItem); - - //Get callback function - var clb = arguments[arguments.length - 1]; - if (typeof clb !== 'function') { - clb = undefined; - } - - if (virtualEntitySet) { - var q = Container.createQueryable(virtualEntitySet, es); - if (clb) { - es.isTerminated = true; - return q._runQuery(clb); - } - return q; - } - else { - var returnType = cfg.returnType ? Container.resolveType(cfg.returnType) : null; - - var q = Container.createQueryable(context, es); - q.defaultType = returnType || $data.Object; - - if (returnType === $data.Queryable) { - q.defaultType = Container.resolveType(cfg.elementType); - if (clb) { - es.isTerminated = true; - return q._runQuery(clb); - } - return q; - } - es.isTerminated = true; - return q._runQuery(clb); - } - }; - }; - - var params = []; - if (cfg.params) { - for (var i = 0; i < cfg.params.length; i++) { - var param = cfg.params[i]; - for (var name in param) { - params.push({ - name: name, - type: param[name] - }); - } - } - } - $data.typeSystem.extend(fn, cfg, { params: params }); - - return fn; - }, - _convertLogicalTypeNameToPhysical: function (name) { - return name + '_$db$'; - }, - _storageModelCache: { - get: function () { - if (!this.__storageModelCache) - this.__storageModelCache = {}; - return this.__storageModelCache; - }, - set: function () { - //todo exception - } - } -}); -$data.Class.define('$data.QueryProvider', null, null, -{ - //TODO: instance member????? - constructor: function () { this.requiresExpressions= false }, - executeQuery: function (queryable, resultHandler) { - }, - getTraceString: function (queryable) { - } -}, null);$data.Class.define('$data.ModelBinder', null, null, { - - constructor: function (context) { - this.context = context; - this.providerName = null; - if (this.context.storageProvider && typeof this.context.storageProvider.getType === 'function') { - this.references = !(this.context.storageProvider.providerConfiguration.modelBinderOptimization || false); - for (var i in $data.RegisteredStorageProviders) { - if ($data.RegisteredStorageProviders[i] === this.context.storageProvider.getType()) { - this.providerName = i; - } - } - } - }, - - _deepExtend: function (o, r) { - if (o === null || o === undefined) { - return r; - } - for (var i in r) { - if (o.hasOwnProperty(i)) { - if (typeof r[i] === 'object') { - if (Array.isArray(r[i])) { - for (var j = 0; j < r[i].length; j++) { - if (o[i].indexOf(r[i][j]) < 0) { - o[i].push(r[i][j]); - } - } - } else this._deepExtend(o[i], r[i]); - } - } else { - o[i] = r[i]; - } - } - return this._finalize(o); - }, - - _finalize: function(o){ - if (o instanceof $data.Entity) { - o.changedProperties = undefined; - o.storeToken = this.context.storeToken; - } - return o; - }, - - _buildSelector: function (meta, context) { - if (meta.$selector) { - if (!(Array.isArray(meta.$selector))) { - meta.$selector = [meta.$selector]; - } - - for (var i = 0; i < meta.$selector.length; i++) { - var selector = meta.$selector[i].replace('json:', ''); - context.src += 'if('; - var path = selector.split('.'); - for (var j = 0; j < path.length; j++) { - context.src += 'di.' + path.slice(0, j + 1).join('.') + (j < path.length - 1 ? ' && ' : ' !== undefined && typeof di.' + selector + ' === "object"'); - } - context.src += '){di = di.' + selector + ';}' + (i < meta.$selector.length - 1 ? 'else ' : ''); - } - - context.src += 'if (di === null){'; - if (context.iter) context.src += context.iter + ' = null;'; - context.src += 'return null;'; - context.src += '}'; - } - }, - - _buildKey: function (name, type, keys, context, data) { - if (keys) { - var type = Container.resolveType(type); - var typeIndex = Container.getIndex(type); - type = type.fullName || type.name; - context.src += 'var ' + name + 'Fn = function(di){'; - if (!(Array.isArray(keys)) || keys.length == 1) { - if (typeof keys !== 'string') keys = keys[0]; - context.src += 'if (typeof di.' + keys + ' === "undefined") return undefined;'; - context.src += 'if (di.' + keys + ' === null) return null;'; - context.src += 'var key = ("' + type + '_' + typeIndex + '_' + keys + '#" + di.' + keys + ');'; - } else { - context.src += 'var key = "";'; - for (var i = 0; i < keys.length; i++) { - var id = typeof keys[i] !== 'object' ? keys[i] : keys[i].$source; - context.src += 'if (typeof di.' + id + ' === "undefined") return undefined;'; - context.src += 'if (di.' + id + ' === null) return null;'; - context.src += 'key += ("' + type + '_' + typeIndex + '_' + id + '#" + di.' + id + ');'; - } - } - - context.src += 'return key;};'; - } - - context.src += 'var ' + name + ' = ' + (keys ? name + 'Fn(' + (data || 'di') + ')' : 'undefined') + ';'; - }, - - build: function (meta, context) { - if (meta.$selector) { - if (!(Array.isArray(meta.$selector))) meta.$selector = [meta.$selector]; - for (var i = 0; i < meta.$selector.length; i++) { - meta.$selector[i] = meta.$selector[i].replace('json:', ''); - } - } - - if (meta.$value) { - if (typeof meta.$value === 'function') { - context.src += 'var di = di || data;'; - context.src += 'var fn = function(){ return meta' + (context.meta.length ? '.' + context.meta.join('.') : '') + '.$value.call(self, meta' + (context.meta.length ? '.' + context.meta.join('.') : '') + ', di); };'; - if (meta.$type) { - var type = Container.resolveName(Container.resolveType(meta.$type)); - var typeIndex = Container.getIndex(Container.resolveType(meta.$type)); - var converter = this.context.storageProvider.fieldConverter.fromDb[type]; - if (converter) { - context.item = 'self.context.storageProvider.fieldConverter.fromDb["' + type + '"](fn())'; - } else { - context.item = 'new (Container.resolveByIndex(' + typeIndex + '))(fn())'; - } - } else context.item = 'fn()'; - } else if (meta.$type) { - var type = Container.resolveName(Container.resolveType(meta.$type)); - var typeIndex = Container.getIndex(Container.resolveType(meta.$type)); - var converter = this.context.storageProvider.fieldConverter.fromDb[type]; - if (converter) { - context.item = 'self.context.storageProvider.fieldConverter.fromDb["' + type + '"](' + meta.$value + ')'; - } else { - context.item = 'new (Container.resolveByIndex(' + typeIndex + '))(' + meta.$value + ')'; - } - } else context.item = meta.$value; - } else if (meta.$source) { - var type = Container.resolveName(Container.resolveType(meta.$type)); - var typeIndex = Container.getIndex(Container.resolveType(meta.$type)); - var converter = this.context.storageProvider.fieldConverter.fromDb[type]; - var item = '_' + type.replace(/\./gi, '_') + '_'; - if (!context.forEach) context.src += 'var di = data;'; - context.item = item; - this._buildSelector(meta, context); - if (converter) { - context.src += 'var ' + item + ' = self.context.storageProvider.fieldConverter.fromDb["' + type + '"](di.' + meta.$source + ');'; - } else { - context.src += 'var ' + item + ' = new (Container.resolveByIndex(' + typeIndex + '))(di.' + meta.$source + ');'; - } - } else if (meta.$item) { - context.meta.push('$item'); - var iter = (context.item && context.current ? context.item + '.' + context.current : (context.item ? context.item : 'result')); - context.iter = iter; - if (iter.indexOf('.') < 0) context.src += 'var ' + iter + ';'; - context.src += 'var fn = function(di){'; - if (meta.$selector) { - context.src += 'if (typeof di !== "undefined" && !(Array.isArray(di))){'; - this._buildSelector(meta, context); - context.src += '}'; - } - if (this.references && meta.$keys) this._buildKey('forKey', meta.$type, meta.$keys, context); - //else if (this.references && meta.$item && meta.$item.$keys) this._buildKey('forKey', meta.$type, meta.$item.$keys, context); - //else context.src += 'var forKey = typeof itemKey !== "undefined" ? itemKey : undefined;'; - /*context.src += 'if (typeof forKey !== "undefined" && forKey){'; - context.src += 'if (cache[forKey]){'; - context.src += iter + ' = cache[forKey];'; - context.src += '}else{'; - context.src += iter + ' = [];'; - context.src += 'cache[forKey] = ' + iter + ';'; - context.src += '}'; - context.src += '}else{'; - context.src += iter + ' = [];'; - context.src += '}';*/ - context.src += iter + ' = typeof ' + iter + ' == "undefined" ? [] : ' + iter + ';'; - //context.src += iter + ' = [];'; - if (this.references && meta.$item.$keys) { - var keycacheName = 'keycache_' + iter.replace(/\./gi, '_'); - context.src += 'var ' + keycacheName + ';'; - context.src += 'var kci = keycacheIter.indexOf(' + iter + ');'; - context.src += 'if (kci < 0){'; - context.src += keycacheName + ' = [];'; - context.src += 'keycache.push(' + keycacheName + ');'; - context.src += 'keycacheIter.push(' + iter + ');'; - context.src += '}else{'; - context.src += keycacheName + ' = keycache[kci];'; - context.src += '}'; - //context.src += 'var ' + keycacheName + ' = ' + (meta.$item.$keys ? '[]' : 'null') + ';'; - } - context.iter = undefined; - context.forEach = true; - var itemForKey = 'itemForKey_' + iter.replace(/\./gi, '_'); - context.src += 'var forEachFn = function(di, i){'; - context.src += 'var diBackup = di;'; - if (this.providerName == "sqLite" && this.references && meta.$item.$keys) this._buildKey(itemForKey, meta.$type, meta.$item.$keys, context); - var item = context.item || 'iter'; - context.item = item; - if (!meta.$item.$source) { - this._buildSelector(meta.$item, context); - } - this.build(meta.$item, context); - if (this.references && meta.$keys) { - context.src += 'if (forKey){'; - context.src += 'if (cache[forKey]){'; - context.src += iter + ' = cache[forKey];'; - context.src += 'if (' + iter + '.indexOf(' + (context.item || item) + ') < 0){'; - context.src += iter + '.push(' + (context.item || item) + ');'; - context.src += '}}else{'; - context.src += 'cache[forKey] = ' + iter + ';'; - context.src += iter + '.push(' + (context.item || item) + ');'; - context.src += '}}else{'; - if (this.references && meta.$item.$keys) this._buildKey('cacheKey', meta.$type, meta.$item.$keys, context, 'diBackup'); - context.src += 'if (typeof cacheKey != "undefined" && cacheKey !== null){'; - context.src += 'if (keycache_' + iter.replace(/\./gi, '_') + ' && cacheKey){'; - context.src += 'if (keycache_' + iter.replace(/\./gi, '_') + '.indexOf(cacheKey) < 0){'; - context.src += iter + '.push(' + (context.item || item) + ');'; - context.src += 'keycache_' + iter.replace(/\./gi, '_') + '.push(cacheKey);'; - context.src += '}'; - context.src += '}else{'; - context.src += iter + '.push(' + (context.item || item) + ');'; - context.src += '}'; - context.src += '}'; - context.src += '}'; - } else { - if (this.references && meta.$item.$keys) { - context.src += 'if (typeof ' + itemForKey + ' !== "undefined" && ' + itemForKey + ' !== null){'; - context.src += 'if (typeof keycache_' + iter.replace(/\./gi, '_') + ' !== "undefined" && ' + itemForKey + '){'; - context.src += 'if (keycache_' + iter.replace(/\./gi, '_') + '.indexOf(' + itemForKey + ') < 0){'; - context.src += iter + '.push(' + (context.item || item) + ');'; - context.src += 'keycache_' + iter.replace(/\./gi, '_') + '.push(' + itemForKey + ');' - context.src += '}}else{'; - context.src += iter + '.push(' + (context.item || item) + ');'; - context.src += '}}else{'; - context.src += iter + '.push(' + (context.item || item) + ');'; - context.src += '}'; - /*context.src += 'if (typeof itemKey !== "undefined" && itemKey !== null){'; - context.src += 'if (typeof keycache_' + iter.replace(/\./gi, '_') + ' !== "undefined" && itemKey){'; - context.src += 'if (keycache_' + iter.replace(/\./gi, '_') + '.indexOf(itemKey) < 0){'; - context.src += iter + '.push(' + (context.item || item) + ');'; - context.src += 'keycache_' + iter.replace(/\./gi, '_') + '.push(itemKey);' - context.src += '}}else{'; - context.src += iter + '.push(' + (context.item || item) + ');'; - context.src += '}}else{'; - context.src += iter + '.push(' + (context.item || item) + ');'; - context.src += '}';*/ - } else { - context.src += iter + '.push(' + (context.item || item) + ');'; - } - } - context.src += '};'; - context.src += 'if (Array.isArray(di)) di.forEach(forEachFn);'; - context.src += 'else forEachFn(di, 0);'; - context.forEach = false; - context.item = null; - context.src += '};fn(typeof di === "undefined" ? data : di);' - context.meta.pop(); - } else if (meta.$type) { - if (!context.forEach) { - context.src += 'if (typeof di === "undefined"){'; - context.src += 'var di = data;'; - this._buildSelector(meta, context); - context.src += '}'; - } - var resolvedType = Container.resolveType(meta.$type); - var type = Container.resolveName(resolvedType); - var typeIndex = Container.getIndex(resolvedType); - var isEntityType = resolvedType.isAssignableTo && resolvedType.isAssignableTo($data.Entity); - var item = '_' + type.replace(/\./gi, '_') + '_'; - if (context.item == item) item += 'new_'; - context.item = item; - - - var isPrimitive = false; - if (!meta.$source && !meta.$value && resolvedType !== $data.Array && resolvedType !== $data.Object && !resolvedType.isAssignableTo) - isPrimitive = true; - if (resolvedType === $data.Object || resolvedType === $data.Array) { - var keys = Object.keys(meta); - if (keys.length == 1 || (keys.length == 2 && meta.$selector)) isPrimitive = true; - } - - if (isPrimitive) { - var converter = this.context.storageProvider.fieldConverter.fromDb[type]; - if (converter) { - context.src += 'var ' + item + ' = di != undefined ? self.context.storageProvider.fieldConverter.fromDb["' + type + '"](di) : di;'; - } else { - context.src += 'var ' + item + ' = di;'; - } - } else { - if (this.references && meta.$keys) { - this._buildKey('itemKey', meta.$type, meta.$keys, context); - context.src += 'if (itemKey === null) return null;'; - context.src += 'var ' + item + ';'; - context.src += 'if (itemKey && cache[itemKey]){'; - context.src += item + ' = cache[itemKey];'; - context.src += '}else{'; - if (isEntityType) { - context.src += item + ' = new (Container.resolveByIndex(' + typeIndex + '))(undefined, { setDefaultValues: false });'; - } else { - context.src += item + ' = new (Container.resolveByIndex(' + typeIndex + '))();'; - } - context.src += 'if (itemKey){'; - context.src += 'cache[itemKey] = ' + item + ';'; - context.src += '}'; - context.src += '}'; - } else { - if (isEntityType) { - context.src += 'var ' + item + ' = new (Container.resolveByIndex(' + typeIndex + '))(undefined, { setDefaultValues: false });'; - } else { - context.src += 'var ' + item + ' = new (Container.resolveByIndex(' + typeIndex + '))();'; - } - } - } - for (var i in meta) { - if (i.indexOf('$') < 0) { - context.current = i; - if (!meta[i].$item) { - if (meta[i].$value) { - context.meta.push(i); - var item = context.item; - this.build(meta[i], context); - context.src += item + '.' + i + ' = ' + context.item + ';'; - context.item = item; - context.meta.pop(); - } else if (meta[i].$source) { - context.src += 'var fn = function(di){'; - this._buildSelector(meta[i], context); - if (meta[i].$type) { - var type = Container.resolveName(Container.resolveType(meta[i].$type)); - var typeIndex = Container.getIndex(Container.resolveType(meta[i].$type)); - var converter = this.context.storageProvider.fieldConverter.fromDb[type]; - if (converter) { - context.src += 'return self.context.storageProvider.fieldConverter.fromDb["' + type + '"](di.' + meta[i].$source + ');'; - } else { - context.src += 'return new (Container.resolveByIndex(' + typeIndex + '))(di.' + meta[i].$source + ');'; - } - } else { - context.src += item + '.' + i + ' = di.' + meta[i].$source + ';'; - } - context.src += '};'; - if (meta[i].$type) context.src += item + '.' + i + ' = fn(di);'; - else context.src += 'fn(di);'; - } else if (meta[i].$type) { - context.meta.push(i); - context.src += 'var fn = function(di){'; - this._buildSelector(meta[i], context); - this.build(meta[i], context); - context.src += 'return ' + context.item + ';};'; - if (meta[i].$type === $data.Object) context.src += item + '.' + i + ' = self._deepExtend(' + item + '.' + i + ', fn(di));'; - else context.src += item + '.' + i + ' = fn(di);'; - context.item = item; - context.meta.pop(); - } else if (meta.$type) { - var memDef = Container.resolveType(meta.$type).memberDefinitions.getMember(i); - var type = Container.resolveName(memDef.type); - var entityType = Container.resolveType(meta.$type); - var entityTypeIndex = Container.getIndex(meta.$type); - var converter = this.context.storageProvider.fieldConverter.fromDb[type]; - if (this.providerName && memDef && memDef.converter && memDef.converter[this.providerName] && typeof memDef.converter[this.providerName].fromDb == 'function') { - context.src += item + '.' + i + ' = Container.resolveByIndex("' + entityTypeIndex + '").memberDefinitions.getMember("' + i + '").converter.' + this.providerName + '.fromDb(di.' + meta[i] + ', Container.resolveByIndex("' + entityTypeIndex + '").memberDefinitions.getMember("' + i + '"), self.context, Container.resolveByIndex("' + entityTypeIndex + '"));'; - } else if (converter) { - context.src += item + '.' + i + ' = self.context.storageProvider.fieldConverter.fromDb["' + type + '"](di.' + meta[i] + ');'; - } else { - //var type = Container.resolveName(Container.resolveType(type.memberDefinitions.getMember(i).type)); - var typeIndex = Container.getIndex(Container.resolveType(type.memberDefinitions.getMember(i).type)); - context.src += item + '.' + i + ' = new (Container.resolveByIndex(' + typeIndex + '))(di.' + meta[i] + ');'; - } - } - } else { - context.meta.push(i); - this.build(meta[i], context); - context.item = item; - context.meta.pop(); - } - } - } - context.src += item + ' = self._finalize(' + item + ');'; - } - }, - - call: function (data, meta) { - if (!Object.getOwnPropertyNames(meta).length) { - return data; - } - var context = { - src: '', - meta: [] - }; - context.src += 'var self = this;'; - context.src += 'var result;'; - context.src += 'var cache = {};'; - context.src += 'var keycache = [];'; - context.src += 'var keycacheIter = [];'; - this.build(meta, context); - if (context.item) context.src += 'if (typeof result === "undefined") result = ' + context.item + ';'; - context.src += 'return result;'; - - /*var beautify = require('beautifyjs'); - console.log(beautify.js_beautify(context.src));*/ - - var fn = new Function('meta', 'data', context.src).bind(this); - var ret = fn(meta, data); - return ret; - } -}); -$C('$data.queryBuilder', null, null, { - constructor: function () { - this._fragments = {}; - this.selectedFragment = null; - this._binderConfig = {}; - this.modelBinderConfig = this._binderConfig; - this._binderConfigPropertyStack = []; - }, - selectTextPart: function (name) { - if (!this._fragments[name]) { - this._fragments[name] = { text: '', params: [] }; - } - this.selectedFragment = this._fragments[name]; - }, - getTextPart: function (name) { - return this._fragments[name]; - }, - addText: function (textParticle) { - this.selectedFragment.text += textParticle; - }, - addParameter: function (param) { - this.selectedFragment.params.push(param); - }, - selectModelBinderProperty: function (name) { - this._binderConfigPropertyStack.push(this.modelBinderConfig); - if (!(name in this.modelBinderConfig)) { - this.modelBinderConfig[name] = {}; - } - this.modelBinderConfig = this.modelBinderConfig[name]; - }, - popModelBinderProperty: function () { - if (this._binderConfigPropertyStack.length === 0) { - this.modelBinderConfig = this._binderConfig(); - } else { - this.modelBinderConfig = this._binderConfigPropertyStack.pop(); - } - }, - resetModelBinderProperty: function (name) { - this._binderConfigPropertyStack = []; - this.modelBinderConfig = this._binderConfig; - }, - addKeyField: function (name) { - if(!this.modelBinderConfig['$keys']){ - this.modelBinderConfig['$keys'] = new Array(); - } - this.modelBinderConfig['$keys'].push(name); - } -}); -$C('$data.Query', null, null, -{ - constructor: function (expression, defaultType, context) { - /// - /// - /// - - this.expression = expression; - this.context = context; - - //TODO: expressions get as JSON string?! - - this.expressions = expression; - this.defaultType = defaultType; - this.result = []; - this.rawDataList = []; - this.modelBinderConfig = {}; - this.context = context; - }, - - rawDataList: { dataType: "Array" }, - result: { dataType: "Array" }, - resultType: {}, - buildResultSet: function (ctx) { - var converter = new $data.ModelBinder(this.context); - this.result = converter.call(this.rawDataList, this.modelBinderConfig); - return; - }, - getEntitySets: function(){ - var ret = []; - var ctx = this.context; - - var fn = function(expression){ - if (expression instanceof $data.Expressions.EntitySetExpression){ - if (ret.indexOf(ctx._entitySetReferences[expression.elementType.name]) < 0) - ret.push(ctx._entitySetReferences[expression.elementType.name]); - } - if (expression.source) fn(expression.source); - }; - - fn(this.expression); - - return ret; - } -}, null); -$data.Class.define('$data.Queryable', null, null, -{ - constructor: function (source, rootExpression) { - /// - /// Provides a base class for classes supporting JavaScript Language Query. - /// Provides a base class for classes supporting JavaScript Language Query. - /// - /// - /// - /// - /// Provides a base class for classes supporting JavaScript Language Query. - /// Provides a base class for classes supporting JavaScript Language Query. - /// - /// - /// - - var context = source instanceof $data.EntityContext ? source : source.entityContext; - this.defaultType = source instanceof $data.EntityContext ? null : source.defaultType; - this.entityContext = context; - this.expression = rootExpression; - }, - - filter: function (predicate, thisArg) { - ///Filters a set of entities using a boolean expression. - ///A boolean query expression - ///The query parameters - /// - /// - ///Filters a set of entities using a boolean expression formulated as string. - /// - ///The expression body of the predicate function in string. - ///To reference the lambda parameter use the 'it' context variable. - ///Example: filter("it.Title == 'Hello'") - /// - /// - /// - /// - /// - ///Filters a set of entities using a bool expression formulated as a JavaScript function. - /// - /// - /// - ///Contains the predicate parameters - /// - /// - /// - ///Filtering a set of entities with a predicate function - ///var males = Persons.filter( function( person ) { return person.Gender == 'Male' } ); - /// - /// - ///Filtering a set of entities with a predicate function and parameters - ///var draftables = Persons.filter( function( person ) { - /// return person.Gender == this.gender && person.Age > this.age - /// }, { gender: 'Male', age: 21 }); - /// - /// - ///Filtering a set of entities with a predicate as a string and parameters - ///var draftables = Persons.filter("it.Gender == this.gender && it.Age > this.age", - /// { gender: 'Male', age: 21 }); - /// - /// - if (arguments.length === 3) { - predicate = "it." + arguments[0] + - (arguments[1][0] === "." ? (arguments[1] + "(param)") : (" " + arguments[1] + " param")); - thisArg = { param : arguments[2] } - } - this._checkOperation('filter'); - var expression = Container.createCodeExpression(predicate, thisArg); - var expressionSource = this.expression; - if (this.expression instanceof $data.Expressions.FilterExpression) { - expressionSource = this.expression.source; - - var operatorResolution = this.entityContext.storageProvider.resolveBinaryOperator("and"); - expression = Container.createSimpleBinaryExpression(this.expression.selector, expression, "and", "filter", "boolean", operatorResolution); - } - var exp = Container.createFilterExpression(expressionSource, expression); - var q = Container.createQueryable(this, exp); - return q; - }, - where: function (predicate, params) { - ///Where is a convenience alias for C# developers. Use filter instead. - /// - return this.filter(predicate, params); - }, - - map: function (projection, thisArg, mappedTo) { - /// Map specifies the shape or type of each returned element. You can specify whether your results will consist of complete Person objects, just one member, a subset of members, or some completely different result type based on a computation or new object creation. When map produces something other than a copy of the source element, the operation is called a projection. The use of projections to transform data is a powerful capability of JavaScript Language Query expressions. - /// A projection expression - /// The query parameters - /// - /// - /// Map specifies the shape or type of each returned element. You can specify whether your results will consist of complete Person objects, just one member, a subset of members, or some completely different result type based on a computation or new object creation. When map produces something other than a copy of the source element, the operation is called a projection. The use of projections to transform data is a powerful capability of JavaScript Language Query expressions. - /// - /// The expression body of the projection function in string. - /// To reference the lambda parameter use the 'it' context variable. - /// Example: map("{ i: it.Id, t: it.Title }") - /// - /// - /// - /// - /// - /// Map specifies the shape or type of each returned element. You can specify whether your results will consist of complete Person objects, just one member, a subset of members, or some completely different result type based on a computation or new object creation. When map produces something other than a copy of the source element, the operation is called a projection. The use of projections to transform data is a powerful capability of JavaScript Language Query expressions. - /// - /// Projection function to specify the shape or type of each returned element. - /// - /// - /// Contains the projection parameters. - /// - /// - /// - /// Projection to get an array of the full name property of a set of Person entities - /// var personFullNames = Persons.map( function( person ) { return person.FullName; } ); - /// - /// - /// Projection to get an array of the required fields of Person entities in an anonymous type. - /// var custom = Persons.map( function( person ) { - /// return { FullName: person.FullName, Info: { Address: person.Location.Address, Phone: person.Phone } }; - /// }); - /// - /// - - this._checkOperation('map'); - var codeExpression = Container.createCodeExpression(projection, thisArg); - var exp = Container.createProjectionExpression(this.expression, codeExpression); - - if (mappedTo === 'default') - exp.projectionAs = this.defaultType; - else if (mappedTo) - exp.projectionAs = Container.resolveType(mappedTo); - else - exp.projectionAs = $data.Object; - - var q = Container.createQueryable(this, exp); - return q; - }, - select: function (projection, thisArg, mappedTo) { - ///Select is a convenience alias for C# developers. Use map instead. - /// - return this.map(projection, thisArg, mappedTo); - }, - - length: function (onResult, transaction) { - /// Returns the number of entities (or projected object) in a query as the callback parameter. - /// A callback function - /// - /// - /// Returns the number of entities (or projected object) in a query as the callback parameter. - /// - /// The callback function to handle the result. - /// - /// - /// - /// - /// Returns the number of entities (or projected object) in a query as the callback parameter. - /// - /// Object of callback functions to handle success and error. - /// Example: { success: function(cnt) { ... }, error: function() { alert("Something went wrong..."); } } - /// - /// - /// - /// Get the count of Person entities. - /// Persons.length( function( cnt ) { alert("There are " + cnt + " person(s) in the database."); } ); - /// - /// - - this._checkOperation('length'); - var pHandler = new $data.PromiseHandler(); - var cbWrapper = pHandler.createCallback(onResult); - - var countExpression = Container.createCountExpression(this.expression); - var preparator = Container.createQueryExpressionCreator(this.entityContext); - try { - var expression = preparator.Visit(countExpression); - this.entityContext.log({ event: "EntityExpression", data: expression }); - - this.entityContext.executeQuery(Container.createQueryable(this, expression), cbWrapper, transaction); - } catch (e) { - cbWrapper.error(e); - } - - return pHandler.getPromise(); - }, - count: function (onResult, transaction) { - ///Count is a convenience alias for C# developers. Use length instead. - /// - return this.length(onResult, transaction); - }, - - forEach: function (iterator, transaction) { - /// Calls the iterator function for all entity (or projected object) in the query. - /// Iterator function - /// - /// - /// Calls the iterator function for all entity (or projected object) in the query. - /// - /// Iterator function to handle the result elements. - /// - /// - /// - /// Log the full name of each Person. - /// Persons.forEach( function( person ) { console.log(person.FullName; } ); - /// - /// - - this._checkOperation('forEach'); - var pHandler = new $data.PromiseHandler(); - function iteratorFunc(items) { items.forEach(iterator); } - var cbWrapper = pHandler.createCallback(iteratorFunc); - - var forEachExpression = Container.createForEachExpression(this.expression); - var preparator = Container.createQueryExpressionCreator(this.entityContext); - try { - var expression = preparator.Visit(forEachExpression); - this.entityContext.log({ event: "EntityExpression", data: expression }); - - this.entityContext.executeQuery(Container.createQueryable(this, expression), cbWrapper, transaction); - } catch (e) { - cbWrapper.error(e); - } - - return pHandler.getPromise(); - }, - - toArray: function (onResult_items, transaction) { - /// Returns the query result as the callback parameter. - /// A callback function - /// - /// - /// Returns the query result as the callback parameter. - /// - /// The callback function to handle the result. - /// - /// - /// - /// - /// Returns the query result as the callback parameter. - /// - /// Object of callback functions to handle success and error. - /// Example: { success: function(result) { ... }, error: function() { alert("Something went wrong..."); } } - /// - /// - /// - /// Get all Person entities. - /// Persons.toArray( function( result ) { console.dir(result); } ); - /// - /// - - if (onResult_items instanceof $data.Array) - { - return this.toArray(function (results) { - onResult_items.length = 0; - results.forEach(function (item, idx) { - onResult_items.push(item); - }); - }); - } - - this._checkOperation('toArray'); - var pHandler = new $data.PromiseHandler(); - var cbWrapper = pHandler.createCallback(onResult_items); - - var toArrayExpression = Container.createToArrayExpression(this.expression); - var preparator = Container.createQueryExpressionCreator(this.entityContext); - try { - var expression = preparator.Visit(toArrayExpression); - this.entityContext.log({ event: "EntityExpression", data: expression }); - - this.entityContext.executeQuery(Container.createQueryable(this, expression), cbWrapper, transaction); - } catch (e) { - cbWrapper.error(e); - } - - return pHandler.getPromise(); - }, - toLiveArray: function (onResult, transaction) { - var self = this; - var result = []; - - var doAction = function (action) { - return function (onResult) { - var pHandler = new $data.PromiseHandler(); - var callback = pHandler.createCallback(onResult); - - var successFunc = function (res) { - result.length = 0; - - var data = res; - $data.typeSystem.extend(result, data); - - result.prev = doAction(function (cb) { - data.prev(cb); - }); - result.next = doAction(function (cb) { - data.next(cb); - }); - - callback.success.apply(this, [result].concat(Array.prototype.slice.call(arguments, 1))); - } - - action({ - success: successFunc, - error: callback.error - }, transaction); - - var promise = pHandler.getPromise(); - $data.typeSystem.extend(result, promise); - - return result; - } - } - - result.refresh = doAction(function (cb) { - self.toArray(cb); - }); - - return result.refresh.apply(result, arguments); - }, - - single: function (filterPredicate, thisArg, onResult, transaction) { - /// Filters a set of entities using a boolean expression and returns a single element or throws an error if more than one element is filtered. - /// A callback function - /// - /// - /// Filters a set of entities using a boolean expression and returns a single element or throws an error if more than one element is filtered. - /// - /// Same as in filter. - /// - /// - /// The callback function to handle the result, same as in toArray. - /// - /// - /// - /// - /// Filters a set of entities using a boolean expression and returns a single element or throws an error if more than one element is filtered. - /// - /// Same as in filter. - /// - /// - /// The callback function to handle the result, same as in toArray. - /// - /// - /// - /// Get "George" from the Person entity set. - /// Persons.single( function( person ) { return person.FirstName == this.name; }, { name: "George" }, { - /// success: function ( result ){ ... }, - /// error: function () { ... } - /// }); - /// - /// - - this._checkOperation('single'); - var q = this; - if (filterPredicate) { - q = this.filter(filterPredicate, thisArg); - } - q = q.take(2); - - var pHandler = new $data.PromiseHandler(); - var cbWrapper = pHandler.createCallback(onResult); - - var singleExpression = Container.createSingleExpression(q.expression); - var preparator = Container.createQueryExpressionCreator(q.entityContext); - try { - var expression = preparator.Visit(singleExpression); - this.entityContext.log({ event: "EntityExpression", data: expression }); - - q.entityContext.executeQuery(Container.createQueryable(q, expression), cbWrapper, transaction); - } catch (e) { - cbWrapper.error(e); - } - - return pHandler.getPromise(); - }, - - some: function (filterPredicate, thisArg, onResult, transaction) { - /// Filters a set of entities using a boolean expression and returns true if the query has any result element. - /// Filter function - /// The query parameters for filter function - /// A callback function - /// - /// - /// Filters a set of entities using a boolean expression and returns true if the query has any result element. - /// - /// Same as in filter. - /// - /// - /// The callback function to handle the result, same as in toArray. - /// - /// - /// - /// - /// Filters a set of entities using a boolean expression and returns true if the query has any result element. - /// - /// Same as in filter. - /// - /// - /// The callback function to handle the result, same as in toArray. - /// - /// - /// - /// Is there any person who's first name is "George"? - /// Persons.some( function( person ) { return person.FirstName == this.name; }, { name: "George" }, { - /// success: function ( result ){ ... }, - /// error: function () { ... } - /// }); - /// - /// - - this._checkOperation('some'); - var q = this; - if (filterPredicate) { - q = this.filter(filterPredicate, thisArg); - } - q = q.take(1); - - var pHandler = new $data.PromiseHandler(); - var cbWrapper = pHandler.createCallback(onResult); - - var someExpression = Container.createSomeExpression(q.expression); - var preparator = Container.createQueryExpressionCreator(q.entityContext); - try { - var expression = preparator.Visit(someExpression); - this.entityContext.log({ event: "EntityExpression", data: expression }); - - q.entityContext.executeQuery(Container.createQueryable(q, expression), cbWrapper, transaction); - } catch (e) { - cbWrapper.error(e); - } - - return pHandler.getPromise(); - }, - - every: function (filterPredicate, thisArg, onResult, transaction) { - /// Filters a set of entities using a boolean expression and returns true if all elements of the EntitySet is in the result set. - /// Filter function - /// The query parameters for filter function - /// A callback function - /// - /// - /// Filters a set of entities using a boolean expression and returns a - /// - /// Same as in filter. - /// - /// - /// The callback function to handle the result, same as in toArray. - /// - /// - /// - /// - /// Filters a set of entities using a boolean expression and returns a single element or throws an error if more than one element is filtered. - /// - /// Same as in filter. - /// - /// - /// The callback function to handle the result, same as in toArray. - /// - /// - /// - /// Result is true when all person are married. - /// Persons.every( function( person ) { return person.Married == true; }, null, { - /// success: function ( result ){ ... }, - /// error: function () { ... } - /// }); - /// - /// - - this._checkOperation('every'); - var q = this; - if (filterPredicate) { - q = this.filter(filterPredicate, thisArg); - } - q = q.take(1); - - var pHandler = new $data.PromiseHandler(); - var cbWrapper = pHandler.createCallback(onResult); - - var everyExpression = Container.createEveryExpression(q.expression); - var preparator = Container.createQueryExpressionCreator(q.entityContext); - try { - var expression = preparator.Visit(everyExpression); - this.entityContext.log({ event: "EntityExpression", data: expression }); - - q.entityContext.executeQuery(Container.createQueryable(q, expression), cbWrapper, transaction); - } catch (e) { - cbWrapper.error(e); - } - - return pHandler.getPromise(); - }, - - - take: function (amount) { - /// Returns only a specified number of elements from the start of the result set. - /// The number of elements to return. - /// - /// - /// Returns only a specified number of elements from the start of the result set. - /// - /// The number of elements to skip. - /// - /// - /// - /// Log the full name of each Person. - /// Persons.take(10).forEach( function( person ) { console.log(person.FullName; } ); - /// - /// - - this._checkOperation('take'); - var constExp = Container.createConstantExpression(amount, "number"); - var takeExp = Container.createPagingExpression(this.expression, constExp, $data.Expressions.ExpressionType.Take); - return Container.createQueryable(this, takeExp); - }, - skip: function (amount) { - /// Skip a specified number of elements from the start of the result set. - /// The number of elements to skip. - /// - /// - /// Skip a specified number of elements from the start of the result set. - /// - /// The number of elements to skip. - /// - /// - /// - /// Log the full name of each Person. - /// Persons.skip(1).take(5).forEach( function( person ) { console.log(person.FullName; } ); - /// - /// - - this._checkOperation('skip'); - var constExp = Container.createConstantExpression(amount, "number"); - var takeExp = Container.createPagingExpression(this.expression, constExp, $data.Expressions.ExpressionType.Skip); - return Container.createQueryable(this, takeExp); - }, - - order: function(selector) { - if (selector === '' || selector === undefined || selector === null) { - return this; - } - if(selector[0] === "-") { - var orderString = "it." + selector.replace("-",""); - return this.orderByDescending(orderString); - } else { - return this.orderBy("it." + selector); - } - - }, - - orderBy: function (selector, thisArg) { - ///Order a set of entities using an expression. - ///An order expression - ///The query parameters - /// - /// - ///Order a set of entities using an expression. - /// - ///The expression body of the order function in string. - ///To reference the lambda parameter use the 'it' context variable. - ///Example: orderBy("it.Id") - /// - /// - /// - /// - /// - ///Order a set of entities using an expression. - /// - /// - /// - ///Contains the predicate parameters - /// - /// - /// - ///Ordering a set of entities with a predicate function - ///var males = Persons.orderBy( function( person ) { return person.Id; } ); - /// - /// - - this._checkOperation('orderBy'); - var codeExpression = Container.createCodeExpression(selector, thisArg); - var exp = Container.createOrderExpression(this.expression, codeExpression, $data.Expressions.ExpressionType.OrderBy); - var q = Container.createQueryable(this, exp); - return q; - }, - orderByDescending: function (selector, thisArg) { - ///Order a set of entities descending using an expression. - ///An order expression - ///The query parameters - /// - /// - ///Order a set of entities descending using an expression. - /// - ///The expression body of the order function in string. - ///To reference the lambda parameter use the 'it' context variable. - ///Example: orderBy("it.Id") - /// - /// - /// - /// - /// - ///Order a set of entities descending using an expression. - /// - /// - /// - ///Contains the predicate parameters - /// - /// - /// - ///Ordering a set of entities with a predicate function - ///var males = Persons.orderByDescending( function( person ) { return person.Id; } ); - /// - /// - - this._checkOperation('orderByDescending'); - var codeExpression = Container.createCodeExpression(selector, thisArg); - var exp = Container.createOrderExpression(this.expression, codeExpression, $data.Expressions.ExpressionType.OrderByDescending); - var q = Container.createQueryable(this, exp); - return q; - }, - - first: function (filterPredicate, thisArg, onResult, transaction) { - /// Filters a set of entities using a boolean expression and returns the first element. - /// A callback function - /// - /// - /// Filters a set of entities using a boolean expression and returns the first element. - /// - /// Same as in filter. - /// - /// - /// The callback function to handle the result, same as in toArray. - /// - /// - /// - /// - /// Filters a set of entities using a boolean expression and returns the first element. - /// - /// Same as in filter. - /// - /// - /// The callback function to handle the result, same as in toArray. - /// - /// - /// - /// Get "George" from the Person entity set. - /// Persons.first( function( person ) { return person.FirstName == this.name; }, { name: "George" }, function ( result ){ ... }); - /// - /// - - this._checkOperation('first'); - var q = this; - if (filterPredicate) { - q = this.filter(filterPredicate, thisArg); - } - q = q.take(1); - - var pHandler = new $data.PromiseHandler(); - var cbWrapper = pHandler.createCallback(onResult); - - var firstExpression = Container.createFirstExpression(q.expression); - var preparator = Container.createQueryExpressionCreator(q.entityContext); - try { - var expression = preparator.Visit(firstExpression); - q.entityContext.log({ event: "EntityExpression", data: expression }); - - q.entityContext.executeQuery(Container.createQueryable(q, expression), cbWrapper, transaction); - } catch (e) { - cbWrapper.error(e); - } - - return pHandler.getPromise(); - }, - - find: function (keyValue, onResult, transaction) { - - var pHandler = new $data.PromiseHandler(); - var cbWrapper = pHandler.createCallback(onResult); - - var keys = this.defaultType.memberDefinitions.getKeyProperties(); - - try { - - if (keys.length === 1 && typeof keyValue !== 'object') { - var keyV = {}; - keyV[keys[0].name] = keyValue; - keyValue = keyV; - } - - if (typeof keyValue !== 'object') { - throw new Exception('Key parameter is invalid'); - } else { - - - var parameters = []; - for (var i = 0; i < keys.length; i++) { - var keyProp = keys[i]; - if (!(keyProp.name in keyValue)) { - throw new Exception('Key value missing'); - } - parameters.push(Container.createConstantExpression(keyValue[keyProp.name], keyProp.type, keyProp.name)); - } - - var operation = this.entityContext.storageProvider.supportedSetOperations['find']; - if (operation) { - - var findExpression = Container.createFindExpression(this.expression, parameters); - var preparator = Container.createQueryExpressionCreator(this.entityContext); - try { - var expression = preparator.Visit(findExpression); - this.entityContext.log({ event: "EntityExpression", data: expression }); - - this.entityContext.executeQuery(Container.createQueryable(this, expression), cbWrapper, transaction); - } catch (e) { - cbWrapper.error(e); - } - - } else { - var predicate = ''; - var params = {} - for (var i = 0; i < parameters.length; i++) { - var param = parameters[i]; - params[param.name] = param.value; - if (i > 0) predicate += ' && '; - predicate += "it." + param.name + " == this." + param.name; - } - - this.single(predicate, params, cbWrapper, transaction); - } - } - } catch (e) { - cbWrapper.error(e); - } - - return pHandler.getPromise(); - }, - - include: function (selector) { - /// Includes the given entity set in the query if it's an inverse property. - /// Entity set name - /// - /// - /// Includes the given entity set in the query if it's an inverse property. - /// - /// The name of the entity set you want to include in the query. - /// - /// - /// - /// Include the Category on every Article. - /// Articles.include("Category"); - /// - /// - - this._checkOperation('include'); - var constExp = Container.createConstantExpression(selector, "string"); - var takeExp = Container.createIncludeExpression(this.expression, constExp); - return Container.createQueryable(this, takeExp); - }, - - withInlineCount: function (selector) { - this._checkOperation('withInlineCount'); - var constExp = Container.createConstantExpression(selector || 'allpages', "string"); - var inlineCountExp = Container.createInlineCountExpression(this.expression, constExp); - return Container.createQueryable(this, inlineCountExp); - }, - - removeAll: function (onResult, transaction) { - /// Delete the query result and returns the number of deleted entities in a query as the callback parameter. - /// A callback function - /// - /// - /// Delete the query result and returns the number of deleted entities in a query as the callback parameter. - /// - /// The callback function to handle the result. - /// - /// - /// - /// - /// Delete the query result and returns the number of deleted entities in a query as the callback parameter. - /// - /// Object of callback functions to handle success and error. - /// Example: { success: function(result) { ... }, error: function() { alert("Something went wrong..."); } } - /// - /// - /// - /// Delete all People who are younger than 18 years old. - /// Persons.filter( function( p ){ return p.Age < 18; } ).removeAll( function( result ) { console.dir(result); } ); - /// - /// - - this._checkOperation('batchDelete'); - var pHandler = new $data.PromiseHandler(); - var cbWrapper = pHandler.createCallback(onResult); - - var batchDeleteExpression = Container.createBatchDeleteExpression(this.expression); - var preparator = Container.createQueryExpressionCreator(this.entityContext); - try { - var expression = preparator.Visit(batchDeleteExpression); - this.entityContext.log({ event: "EntityExpression", data: expression }); - - this.entityContext.executeQuery(Container.createQueryable(this, expression), cbWrapper, transaction); - } catch (e) { - cbWrapper.error(e); - } - - return pHandler.getPromise(); - }, - - - _runQuery: function (onResult_items, transaction) { - var pHandler = new $data.PromiseHandler(); - var cbWrapper = pHandler.createCallback(onResult_items); - - var preparator = Container.createQueryExpressionCreator(this.entityContext); - try { - var expression = preparator.Visit(this.expression); - this.entityContext.log({ event: "EntityExpression", data: expression }); - - this.entityContext.executeQuery(Container.createQueryable(this, expression), cbWrapper, transaction); - } catch (e) { - cbWrapper.error(e); - } - - return pHandler.getPromise(); - }, - - toTraceString: function (name) { - /// Returns the trace string of the query. - /// Name of the execution method (toArray, length, etc.). - /// - /// - /// Returns the trace string of the query. - /// - /// Name of the execution method (toArray, length, etc.). Optional. Default value is "toArray". - /// - /// - /// - /// Get the trace string for Articles.toArray() - /// Articles.toTraceString(); - /// - /// - - var expression = this.expression; - - if (name) { - expression = Container['create' + name + 'Expression'](expression); - } else { - expression = Container.createToArrayExpression(expression); - } - - var preparator = Container.createQueryExpressionCreator(this.entityContext); - expression = preparator.Visit(expression); - - //this.expression = expression; - var q = Container.createQueryable(this, expression) - return q.entityContext.getTraceString(q); - }, - - _checkOperation: function (name) { - var operation = this.entityContext.resolveSetOperations(name); - if (operation.invokable != undefined && !operation.invokable) - Guard.raise(new Exception("Operation '" + name + "' is not invokable with the provider")); - }, - defaultType: {} - -}, null); -///EntitySet is responsible for -/// -creating and holding entityType through schema -/// - provide Add method -/// - provide Delete method -/// - provide Update method -/// - provide queryProvider for queryable - -$data.EntitySchemaConfig = function EntitySchemaConfig() { - this.Name = ""; -}; -$data.entitySetState = { created: 0, defined: 1, active: 2 }; - -$data.Class.defineEx('$data.EntitySet', - [ - { type: $data.Queryable, params: [new ConstructorParameter(1)] } - ], null, -{ - constructor: function (elementType, context, collectionName, eventHandlers, roles) { - /// - /// Represents a typed entity set that is used to perform create, read, update, and delete operations - /// Type of entity set elements, elementType must be subclass of $data.Entity - /// Context of the EntitySet - /// Name of the EntitySet - /// - this.createNew = this[elementType.name] = this.elementType = this.defaultType = elementType; - var self = this; - context['createAdd' + elementType.name] = function (initData) { - var entity = new elementType(initData); - return self.add(entity); - } - this.stateManager = new $data.EntityStateManager(this); - - this.collectionName = collectionName; - this.roles = roles; - - for (var i in eventHandlers){ - this[i] = eventHandlers[i]; - } - }, - - addNew: function(item, cb) { - var callback = $data.typeSystem.createCallbackSetting(cb); - var _item = new this.createNew(item); - this.entityContext.saveChanges(cb); - return _item; - }, - - executeQuery: function (expression, on_ready) { - //var compiledQuery = this.entityContext - var callBack = $data.typeSystem.createCallbackSetting(on_ready); - this.entityContext.executeQuery(expression, callBack); - }, - getTraceString: function (expression) { - return this.entityContext.getTraceString(expression); - }, - setContext: function (entityContext) { - this.entitySetState = $data.entitySetState.active; - this.entityContext = entityContext; - this.entityContext[this.schema.name] = this[this.schema.name]; - }, - _trackEntity: function (entity) { - var trackedEntities = this.entityContext.stateManager.trackedEntities; - for (var i = 0; i < trackedEntities.length; i++) { - if (trackedEntities[i].data === entity) - return; - } - trackedEntities.push({ entitySet: this, data: entity }); - }, - add: function (entity) { - /// - /// Creates a typed entity and adds to the context. - /// The init parameters whish is based on Entity - /// - /// - /// Persons.add({ Name: 'John', Email: 'john@example.com', Age: 30, Gender: 'Male' }); - /// - /// - /// - /// - /// Adds the given entity to the context. - /// The entity to add - /// - /// - /// Persons.add(new $news.Types.Person({ Name: 'John', Email: 'john@example.com', Age: 30, Gender: 'Male' })); - /// - /// - /// - /// - /// var person = new $news.Types.Person({ Name: 'John', Email: 'john@example.com', Age: 30, Gender: 'Male' }); - /// Persons.add(person); - /// - /// - /// - - var data = entity; - if (entity instanceof $data.EntityWrapper) { - data = entity.getEntity(); - } else if (!(entity instanceof this.createNew)) { - data = new this.createNew(entity); - } - data.entityState = $data.EntityState.Added; - data.changedProperties = undefined; - data.context = this.entityContext; - this._trackEntity(data); - return data; - }, - - addMany: function(entities) { - var result = []; - var self = this; - entities.forEach(function (entity) { - result.push(self.add(entity)); - }); - return result; - }, - remove: function (entity) { - /// - /// Creates a typed entity and marks it as Deleted. - /// The init parameters whish is based on Entity - /// - /// Person will be marked as Deleted where an id is 5. Id is a key of entity. - /// Persons.remove({ Id: 5 }); - /// - /// - /// - /// - /// Marks the given entity as Deleted. - /// The entity to remove - /// - /// - /// Persons.remove(person); - /// - /// - /// - /// Person will be marked as Deleted where an Id is 5. Id is a key of entity. - /// Persons.add(new $news.Types.Person({ Id: 5 })); - /// - /// - /// - - var data = entity; - if (entity instanceof $data.EntityWrapper) { - data = entity.getEntity(); - } else if (!(entity instanceof this.createNew)) { - data = new this.createNew(entity); - } - data.entityState = $data.EntityState.Deleted; - data.changedProperties = undefined; - this._trackEntity(data); - }, - attach: function (entity, mode) { - /// - /// Creates a typed entity and adds to the Context with Unchanged state. - /// The init parameters whish is based on Entity - /// - /// - /// Persons.attach({ Id: 5, Email: 'newEmail@example.com' }); - /// - /// - /// - /// - /// Adds to the context and sets state Unchanged. - /// The entity to attach - /// - /// - /// Persons.attach(person); - /// - /// - /// - /// Set an entity's related entities without loading - /// - /// var categoryPromo = new $news.Types.Category({ Id: 5 }); - /// Category.attach(categoryPromo); - /// var article = new $news.Types.Article({ Title: 'New Article title', Body: 'Article body', Category: [ categoryPromo ] }); - /// Article.attach(article); - /// - /// - /// - - var data = entity; - if (entity instanceof $data.EntityWrapper) { - data = entity.getEntity(); - } else if (!(entity instanceof this.createNew)) { - data = new this.createNew(entity); - } - - for (var i = 0; i < this.entityContext.stateManager.trackedEntities.length; i++) { - var current = this.entityContext.stateManager.trackedEntities[i]; - if (current.data === data) - break; - if (current.data.equals(data)) { - Guard.raise(new Exception("Context already contains this entity!!!")); - } - } - - if (mode === true) { - if (data.changedProperties && data.changedProperties.length > 0) { - data.entityState = $data.EntityState.Modified; - } else { - data.entityState = $data.EntityState.Unchanged; - } - } else { - if (typeof mode === "string") mode = $data.EntityAttachMode[mode]; - var attachMode = mode || $data.EntityAttachMode[$data.EntityAttachMode.defaultMode]; - if (typeof attachMode === "function") { - attachMode.call($data.EntityAttachMode, data); - } else { - data.entityState = $data.EntityState.Unchanged; - data.changedProperties = undefined; - } - } - /*if (!keepChanges) { - data.entityState = $data.EntityState.Unchanged; - data.changedProperties = undefined; - }*/ - data.context = this.entityContext; - this._trackEntity(data); - }, - detach: function (entity) { - /// - /// Creates a typed entity and detach from the Context with Detached state. - /// The init parameters whish is based on Entity - /// - /// Person will be Detached where an id is 5. Id is a key of entity. - /// Persons.detach({ Id: 5 }); - /// - /// - /// - /// - /// Detach from the context and sets state Detached. - /// The entity to detach - /// - /// - /// Persons.detach(person); - /// - /// - /// - /// Person will be Detached where an Id is 5. Id is a key of entity. - /// Persons.add(new $news.Types.Person({ Id: 5 })); - /// - /// - /// - - var data = entity; - if (entity instanceof $data.EntityWrapper) { - data = entity.getEntity(); - } else if (!(entity instanceof this.createNew)) { - data = new this.createNew(entity); - } - - var existsItem; - var trackedEnt = this.entityContext.stateManager.trackedEntities; - for (var i = 0; i < trackedEnt.length; i++) { - if (trackedEnt[i].data.equals(data)) - existsItem = trackedEnt[i]; - } - - //var existsItem = this.entityContext.stateManager.trackedEntities.filter(function (i) { return i.data.equals(data); }).pop(); - if (existsItem) { - var idx = this.entityContext.stateManager.trackedEntities.indexOf(existsItem); - entity.entityState = $data.EntityState.Detached; - this.entityContext.stateManager.trackedEntities.splice(idx, 1); - return; - } - }, - attachOrGet: function (entity, mode) { - /// - /// Creates a typed entity and adds to the Context with Unchanged state. - /// The init parameters whish is based on Entity - /// - /// - /// Id is a key of entity. - /// var person = Persons.attachOrGet({ Id: 5 }); - /// - /// - /// - /// - /// If not in context then adds to it and sets state Unchanged. - /// The entity to detach - /// - /// - /// - /// var attachedPerson = Persons.attachOrGet(person); - /// - /// - /// - /// Id is a key of entity. - /// var p = new $news.Types.Person({ Id: 5 }); - /// var attachedPerson = Persons.attachOrGet(p); - /// - /// - /// - - var data = entity; - if (entity instanceof $data.EntityWrapper) { - data = entity.getEntity(); - } else if (!(entity instanceof this.createNew)) { - data = new this.createNew(entity); - } - - var existsItem; - var trackedEnt = this.entityContext.stateManager.trackedEntities; - for (var i = 0; i < trackedEnt.length; i++) { - if (trackedEnt[i].data.equals(data)) - existsItem = trackedEnt[i]; - } - //var existsItem = this.entityContext.stateManager.trackedEntities.filter(function (i) { return i.data.equals(data); }).pop(); - if (existsItem) { - return existsItem.data; - } - - if (typeof mode === "string") mode = $data.EntityAttachMode[mode]; - var attachMode = mode || $data.EntityAttachMode[$data.EntityAttachMode.defaultMode]; - if (typeof attachMode === "function") { - attachMode.call($data.EntityAttachMode, data); - } else { - data.entityState = $data.EntityState.Unchanged; - data.changedProperties = undefined; - } - //data.entityState = $data.EntityState.Unchanged; - //data.changedProperties = undefined; - data.context = this.entityContext; - this._trackEntity(data); - return data; - }, - //find: function (keys) { - // //todo global scope - // if (!this.entityKeys) { - // this.entityKeys = this.createNew.memberDefinition.filter(function (prop) { return prop.key; }, this); - // } - // this.entityContext.stateManager.trackedEntities.forEach(function (item) { - // if (item.entitySet == this) { - // var isOk = true; - // this.entityKeys.forEach(function (item, index) { isOK = isOk && (item.data[item.name] == keys[index]); }, this); - // if (isOk) { - // return item.data; - // } - // } - // }, this); - // //TODO: db call - // return null; - //}, - loadItemProperty: function (entity, memberDefinition, callback) { - /// - /// Loads a property of the entity through the storage provider. - /// Entity object - /// Property name - /// - /// Callback function - /// - /// - /// - /// - /// - /// Loads a property of the entity through the storage provider. - /// Entity object - /// Property name - /// - /// Success and error callbacks definition. - /// Example: [code]{ success: function(db) { .. }, error: function() { .. } }[/code] - /// - /// - /// - /// - /// Loads a property of the entity through the storage provider. - /// Entity object - /// Property definition - /// - /// Callback function - /// - /// - /// - /// - /// - /// Loads a property of the entity through the storage provider. - /// Entity object - /// Property definition - /// - /// Success and error callbacks definition. - /// Example: [code]{ success: function(db) { .. }, error: function() { .. } }[/code] - /// - /// - /// - - return this.entityContext.loadItemProperty(entity, memberDefinition, callback); - }, - saveChanges: function () { - return this.entityContext.saveChanges.apply(this.entityContext, arguments); - }, - addProperty: function (name, getter, setter) { - return this.elementType.addProperty.apply(this.elementType, arguments); - }, - expression: { - get: function () { - if (!this._expression) { - var ec = Container.createEntityContextExpression(this.entityContext); - //var name = entitySet.collectionName; - //var entitySet = this.entityContext[entitySetName]; - var memberdef = this.entityContext.getType().getMemberDefinition(this.collectionName); - var es = Container.createEntitySetExpression(ec, - Container.createMemberInfoExpression(memberdef), null, - this); - this._expression = es; - } - - return this._expression; - }, - set: function (value) { - this._expression = value; - } - }, - getFieldUrl: function (keys, field) { - return this.entityContext.getFieldUrl(keys, field, this); - }, - bulkInsert: function (fields, datas, callback) { - return this.entityContext.bulkInsert(this, fields, datas, callback); - } -}, null); -$data.EntityState = { - Detached:0, - Unchanged: 10, - Added: 20, - Modified: 30, - Deleted: 40 -};$data.Class.define("$data.EntityAttachMode", null, null, {}, { - defaultMode: 'Default', - AllChanged: function (data) { - var memDefs = data.getType().memberDefinitions.getPublicMappedProperties(); - for (var i = 0; i < memDefs.length; i++) { - data._setPropertyChanged(memDefs[i]); - } - data.entityState = $data.EntityState.Modified; - }, - KeepChanges: function (data) { - if (data.changedProperties && data.changedProperties.length > 0) { - data.entityState = $data.EntityState.Modified; - } else { - data.entityState = $data.EntityState.Unchanged; - } - }, - Default: function (data) { - data.entityState = $data.EntityState.Unchanged; - data.changedProperties = undefined; - } -});$data.Class.define('$data.EntityStateManager', null, null, -{ - constructor: function (entityContext) { - this.entityContext = null; - this.trackedEntities = []; - this.init(entityContext); - }, - init: function (entityContext) { - this.entityContext = entityContext; - }, - reset: function () { - this.trackedEntities = []; - } -}, null);$data.Class.define('$data.ItemStoreClass', null, null, { - constructor: function () { - var self = this; - self.itemStoreConfig = { - aliases: {}, - contextTypes: {} - } - - self.resetStoreToDefault('local', true); - $data.addStore = function () { - return self.addItemStoreAlias.apply(self, arguments); - }; - $data.implementation = self.implementation; - - $data.Entity.addMember('storeToken', { - get: function () { - if (this.storeConfigs && this.storeConfigs['default']) - return this.storeConfigs.stores[this.storeConfigs['default']]; - }, - set: function (value) { - self._setTypeStoreConfig(this, 'default', value); - } - }, true); - }, - itemStoreConfig: {}, - - addItemStoreAlias: function (name, contextFactoryOrToken, isDefault) { - var self = this; - var promise = new $data.PromiseHandler(); - var callback = promise.createCallback(); - - if ('string' === typeof name) { - //storeToken - if ('object' === typeof contextFactoryOrToken && 'factory' in contextFactoryOrToken) { - var type = Container.resolveType(contextFactoryOrToken.typeName); - - self.itemStoreConfig.aliases[name] = contextFactoryOrToken.factory; - self.itemStoreConfig.contextTypes[name] = type; - if (isDefault) { - self.itemStoreConfig['default'] = name; - } - - callback.success(); - return promise.getPromise(); - } - //contextFactory - else if ('function' === typeof contextFactoryOrToken) { - var preContext = contextFactoryOrToken(); - var contextPromise; - if (preContext && preContext instanceof $data.EntityContext) { - callback.success(preContext); - contextPromise = promise.getPromise(); - } else { - contextPromise = preContext; - } - - return contextPromise.then(function (ctx) { - if (typeof ctx === 'function') { - //factory resolve factory - return self.addItemStoreAlias(name, ctx, isDefault); - } - - if (ctx instanceof $data.EntityContext) { - return ctx.onReady() - .then(function (ctx) { - self.itemStoreConfig.aliases[name] = contextFactoryOrToken; - self.itemStoreConfig.contextTypes[name] = ctx.getType(); - if (isDefault) { - self.itemStoreConfig['default'] = name; - } - - return ctx; - }); - } else { - promise = new $data.PromiseHandler(); - callback = promise.createCallback(); - callback.error(new Exception('factory dont have context instance', 'Invalid arguments')); - return promise.getPromise(); - } - }); - } - } - - callback.error(new Exception('Name or factory missing', 'Invalid arguments')); - return promise.getPromise(); - }, - resetStoreToDefault: function (name, isDefault) { - this.itemStoreConfig.aliases[name] = this._getDefaultItemStoreFactory; - delete this.itemStoreConfig.contextTypes[name]; - if (isDefault) { - this.itemStoreConfig['default'] = name; - } - }, - _setStoreAlias: function (entity, storeToken) { - if ('object' === typeof storeToken && !entity.storeToken) - entity.storeToken = storeToken - return entity; - }, - _getStoreAlias: function (entity, storeAlias) { - var type; - if (entity instanceof $data.Entity) { - var alias = storeAlias || entity.storeToken; - if (alias) { - return alias; - } else { - type = entity.getType(); - } - } else { - type = entity; - } - - return storeAlias || (type.storeConfigs ? type.storeConfigs['default'] : undefined) || type.storeToken; - }, - _getStoreContext: function (aliasOrToken, type, nullIfInvalid) { - var contextPromise = this._getContextPromise(aliasOrToken, type); - - if (!contextPromise || contextPromise instanceof $data.EntityContext) { - var promise = new $data.PromiseHandler(); - var callback = promise.createCallback(); - callback.success(contextPromise); - contextPromise = promise.getPromise(); - } - - return contextPromise.then(function (context) { - if (context instanceof $data.EntityContext) { - return context.onReady(); - } else if (nullIfInvalid) { - return null; - } else { - var promise = new $data.PromiseHandler(); - var callback = promise.createCallback(); - callback.error(new Exception('factory return type error', 'Error')); - return promise.getPromise(); - } - }); - }, - _getContextPromise: function (aliasOrToken, type) { - /*Token*/ - if (aliasOrToken && 'object' === typeof aliasOrToken && 'function' === typeof aliasOrToken.factory) { - return aliasOrToken.factory(type); - } else if (aliasOrToken && 'object' === typeof aliasOrToken && 'object' === typeof aliasOrToken.args && 'string' === typeof aliasOrToken.typeName) { - var type = Container.resolveType(aliasOrToken.typeName); - return new type(JSON.parse(JSON.stringify(aliasOrToken.args))); - } - /*resolve alias from type (Token)*/ - else if (aliasOrToken && 'string' === typeof aliasOrToken && type.storeConfigs && type.storeConfigs.stores[aliasOrToken] && typeof type.storeConfigs.stores[aliasOrToken].factory === 'function') { - return type.storeConfigs.stores[aliasOrToken].factory(); - } - /*resolve alias from type (constructor options)*/ - else if (aliasOrToken && 'string' === typeof aliasOrToken && type.storeConfigs && type.storeConfigs.stores[aliasOrToken]) { - return this._getDefaultItemStoreFactory(type, type.storeConfigs.stores[aliasOrToken]); - } - /*resolve alias from ItemStore (factories)*/ - else if (aliasOrToken && 'string' === typeof aliasOrToken && this.itemStoreConfig.aliases[aliasOrToken]) { - return this.itemStoreConfig.aliases[aliasOrToken](type); - } - /*token is factory*/ - else if (aliasOrToken && 'function' === typeof aliasOrToken) { - return aliasOrToken(); - } - /*default no hint*/ - else { - return this.itemStoreConfig.aliases[this.itemStoreConfig['default']](type); - } - - }, - _getStoreEntitySet: function (storeAlias, instanceOrType) { - var aliasOrToken = this._getStoreAlias(instanceOrType, storeAlias); - var type = ("function" === typeof instanceOrType) ? instanceOrType : instanceOrType.getType();; - - return this._getStoreContext(aliasOrToken, type) - .then(function (ctx) { - var entitySet = ctx.getEntitySetFromElementType(type); - if (!entitySet) { - var d = new $data.PromiseHandler(); - var callback = d.createCallback(); - callback.error("EntitySet not exist for " + type.fullName); - return d.getPromise(); - } - return entitySet; - }); - }, - _getDefaultItemStoreFactory: function (instanceOrType, initStoreConfig) { - if (instanceOrType) { - var type = ("function" === typeof instanceOrType) ? instanceOrType : instanceOrType.getType(); - var typeName = $data.Container.resolveName(type) + "_items"; - var typeName = typeName.replace(/\./g, "_"); - - var storeConfig = $data.typeSystem.extend({ - collectionName: initStoreConfig && initStoreConfig.collectionName ? initStoreConfig.collectionName : 'Items', - tableName: typeName, - initParam: { provider: 'local', databaseName: typeName } - }, initStoreConfig); - - var contextDef = {}; - contextDef[storeConfig.collectionName] = { type: $data.EntitySet, elementType: type } - if (storeConfig.tableName) - contextDef[storeConfig.collectionName]['tableName'] = storeConfig.tableName; - - var inMemoryType = $data.EntityContext.extend(typeName, contextDef); - var ctx = new inMemoryType(storeConfig.initParam); - if (initStoreConfig && typeof initStoreConfig === 'object') - initStoreConfig.factory = ctx._storeToken.factory; - return ctx; - } - return undefined; - }, - implementation: function (name, contextOrAlias) { - var self = $data.ItemStore; - var result; - - if (typeof contextOrAlias === 'string') { - contextOrAlias = self.itemStoreConfig.contextTypes[contextOrAlias] - } else if (contextOrAlias instanceof $data.EntityContext) { - contextOrAlias = contextOrAlias.getType(); - } else if (!(typeof contextOrAlias === 'function' && contextOrAlias.isAssignableTo)) { - contextOrAlias = self.itemStoreConfig.contextTypes[self.itemStoreConfig['default']]; - } - - if (contextOrAlias) { - result = self._resolveFromContext(contextOrAlias, name); - } - - if (!result) { - result = Container.resolveType(name); - } - - return result; - }, - _resolveFromContext: function (contextType, name) { - var memDefs = contextType.memberDefinitions.getPublicMappedProperties(); - for (var i = 0; i < memDefs.length; i++) { - var memDef = memDefs[i]; - if (memDef.type) { - var memDefType = Container.resolveType(memDef.type); - if (memDefType.isAssignableTo && memDefType.isAssignableTo($data.EntitySet)) { - var elementType = Container.resolveType(memDef.elementType); - if (elementType.name === name) { - return elementType; - } - } - } - } - return null; - }, - - - //Entity Instance - EntityInstanceSave: function (storeAlias, hint) { - var self = $data.ItemStore; - var entity = this; - return self._getStoreEntitySet(storeAlias, entity) - .then(function (entitySet) { - return self._getSaveMode(entity, entitySet, hint, storeAlias) - .then(function (mode) { - mode = mode || 'add'; - switch (mode) { - case 'add': - entitySet.add(entity); - break; - case 'attach': - entitySet.attach(entity, true); - entity.entityState = $data.EntityState.Modified; - break; - default: - var d = new $data.PromiseHandler(); - var callback = d.createCallback(); - callback.error('save mode not supported: ' + mode); - return d.getPromise(); - } - - return entitySet.entityContext.saveChanges() - .then(function () { self._setStoreAlias(entity, entitySet.entityContext.storeToken); return entity; }); - }); - }); - }, - EntityInstanceRemove: function (storeAlias) { - var self = $data.ItemStore; - var entity = this; - return self._getStoreEntitySet(storeAlias, entity) - .then(function (entitySet) { - entitySet.remove(entity); - - return entitySet.entityContext.saveChanges() - .then(function () { return entity; }); - }); - }, - EntityInstanceRefresh: function (storeAlias, keepStore) { - var self = $data.ItemStore; - var entity = this; - var entityType = entity.getType(); - - var key = self._getKeyObjectFromEntity(entity, entityType); - - return entityType.read(key, storeAlias) - .then(function (loadedEntity) { - entityType.memberDefinitions.getPublicMappedProperties().forEach(function (memDef) { - entity[memDef.name] = loadedEntity[memDef.name]; - }); - entity.storeToken = (keepStore ? entity.storeToken : undefined) || loadedEntity.storeToken; - entity.changedProperties = undefined; - return entity; - }); - }, - - //Entity Type - EntityInheritedTypeProcessor: function (type) { - var self = $data.ItemStore; - type.readAll = self.EntityTypeReadAll(type); - type.read = self.EntityTypeRead(type); - type.removeAll = self.EntityTypeRemoveAll(type); - type.remove = self.EntityTypeRemove(type); - type.get = self.EntityTypeGet(type); //Not complete - type.save = self.EntityTypeSave(type); - type.addMany = self.EntityTypeAddMany(type); - type.itemCount = self.EntityTypeItemCount(type); - type.query = self.EntityTypeQuery(type); - type.takeFirst = self.EntityTypeTakeFirst(type); - - type.setStore = self.EntityTypeSetStore(type); - }, - EntityTypeReadAll: function (type) { - return function (storeAlias) { - var self = $data.ItemStore; - return self._getStoreEntitySet(storeAlias, type) - .then(function (entitySet) { - return entitySet.forEach(function (item) { self._setStoreAlias(item, entitySet.entityContext.storeToken); }); - }); - } - }, - EntityTypeRemoveAll: function (type) { - return function (storeAlias) { - var self = $data.ItemStore; - return self._getStoreEntitySet(storeAlias, type) - .then(function (entitySet) { - return entitySet.toArray().then(function (items) { - items.forEach(function (item) { - entitySet.remove(item); - }); - - return entitySet.entityContext.saveChanges() - .then(function () { return items; }); - }); - }); - } - }, - EntityTypeRead: function (type) { - return function (key, storeAlias) { - var self = $data.ItemStore; - return self._getStoreEntitySet(storeAlias, type) - .then(function (entitySet) { - try { - var singleParam = self._findByIdQueryable(entitySet, key); - return entitySet.single(singleParam.predicate, singleParam.thisArgs) - .then(function (item) { return self._setStoreAlias(item, entitySet.entityContext.storeToken); }); - } catch (e) { - var d = new $data.PromiseHandler(); - var callback = d.createCallback(); - callback.error(e); - return d.getPromise(); - } - }); - }; - }, - EntityTypeGet: function (type) { - return function (key, storeAlias) { - var self = $data.ItemStore; - var item = new type(self._getKeyObjectFromEntity(key)); - item.refresh(storeAlias); - return item; - }; - }, - EntityTypeSave: function (type) { - return function (initData, storeAlias, hint) { - - var self = $data.ItemStore; - var instance = new type(initData); - return instance.save(storeAlias, hint); - } - }, - EntityTypeAddMany: function (type) { - return function (initDatas, storeAlias) { - var self = $data.ItemStore; - return self._getStoreEntitySet(storeAlias, type) - .then(function (entitySet) { - var items = entitySet.addMany(initDatas); - return entitySet.entityContext.saveChanges() - .then(function () { - return items; - }); - }); - } - }, - EntityTypeRemove: function (type) { - return function (key, storeAlias) { - var self = $data.ItemStore; - var entityPk = type.memberDefinitions.getKeyProperties(); - var entity; - if (entityPk.length === 1) { - var obj = {}; - obj[entityPk[0].name] = key; - entity = new type(obj); - } else { - entity = new type(key); - } - return entity.remove(storeAlias); - } - }, - EntityTypeItemCount: function (type) { - return function (storeAlias) { - var self = $data.ItemStore; - return self._getStoreEntitySet(storeAlias, type) - .then(function (entitySet) { - return entitySet.length(); - }); - } - }, - EntityTypeQuery: function (type) { - return function (predicate, thisArg, storeAlias) { - var self = $data.ItemStore; - return self._getStoreEntitySet(storeAlias, type) - .then(function (entitySet) { - return entitySet.filter(predicate, thisArg).forEach(function (item) { self._setStoreAlias(item, entitySet.entityContext.storeToken); }); - }); - } - }, - EntityTypeTakeFirst: function (type) { - return function (predicate, thisArg, storeAlias) { - var self = $data.ItemStore; - return self._getStoreEntitySet(storeAlias, type) - .then(function (entitySet) { - return entitySet.first(predicate, thisArg) - .then(function (item) { return self._setStoreAlias(item, entitySet.entityContext.storeToken); }); - }); - } - }, - - EntityTypeSetStore: function (type) { - return function (name, config) { - if (typeof name === 'object' && typeof config === 'undefined') { - config = name; - name = 'default'; - } - - var self = $data.ItemStore; - - var defStoreConfig = {}; - if (config) { - if (config.tableName) { - defStoreConfig.tableName = config.tableName; - delete config.tableName; - } - - if (config.collectionName) { - defStoreConfig.collectionName = config.collectionName; - delete config.collectionName; - } - - if (typeof config.dataSource === 'string') { - var ds = config.dataSource; - if (ds.lastIndexOf('/') === ds.length - 1) { - ds = ds.substring(0, ds.lastIndexOf('/')); - } - var parsedApiUrl = ds.substring(0, ds.lastIndexOf('/')); - if (!defStoreConfig.tableName) - defStoreConfig.tableName = ds.substring(ds.lastIndexOf('/') + 1); - - var provider = config.provider || config.name; - switch (provider) { - case 'oData': - config.oDataServiceHost = config.oDataServiceHost || parsedApiUrl; - break; - case 'webApi': - config.apiUrl = config.apiUrl || parsedApiUrl; - break; - default: - break; - } - } - - - } else { - config = { name: 'local' }; - } - - defStoreConfig.initParam = config; - self._setTypeStoreConfig(type, name, defStoreConfig); - - return type; - } - }, - _setTypeStoreConfig: function(type, name, config){ - if (!type.storeConfigs) { - type.storeConfigs = { - stores: {} - }; - } - type.storeConfigs.stores[name] = config; - if (name === 'default') { - type.storeConfigs['default'] = name; - } - }, - - _findByIdQueryable: function (set, keys) { - var keysProps = set.defaultType.memberDefinitions.getKeyProperties(); - if (keysProps.length > 1 && keys && 'object' === typeof keys) { - var predicate = "", thisArgs = {}; - for (var i = 0; i < keysProps.length; i++) { - if (i > 0) predicate += " && "; - - var key = keysProps[i]; - predicate += "it." + key.name + " == this." + key.name; - thisArgs[key.name] = keys[key.name]; - } - - return { - predicate: predicate, - thisArgs: thisArgs - }; - } else if (keysProps.length === 1) { - return { - predicate: "it." + keysProps[0].name + " == this.value", - thisArgs: { value: keys } - }; - } else { - throw 'invalid keys'; - } - }, - _getKeyObjectFromEntity: function (obj, entityType) { - var key; - var keyDefs = entityType.memberDefinitions.getKeyProperties(); - if (keyDefs.length === 1) - key = obj && typeof obj === 'object' ? obj[keyDefs[0].name] : obj; - else { - key = {}; - - for (var i = 0; i < keyDefs.length; i++) { - key[keyDefs[0].name] = obj ? obj[keyDefs[0].name] : obj; - } - } - - return key; - }, - _getSaveMode: function (entity, entitySet, hint, storeAlias) { - var self = this; - var promise = new $data.PromiseHandler(); - var callback = promise.createCallback(); - var entityType = entity.getType(); - - switch (true) { - case hint === 'update': - callback.success('attach'); break; - case hint === 'new': - callback.success('add'); break; - case false === entityType.memberDefinitions.getKeyProperties().every(function (keyDef) { return entity[keyDef.name]; }): - callback.success('add'); break; - case !!entity.storeToken: - callback.success('attach'); break; - break; - default: - //use the current entity store informations - storeAlias = this._getStoreAlias(entity, storeAlias); - entityType.read(self._getKeyObjectFromEntity(entity, entityType), storeAlias) - .then(function () { callback.success('attach'); }) - .fail(function () { callback.success('add'); }); - break; - } - - return promise.getPromise(); - }, - - //EntityContext - ContextRegister: function (storageProviderCfg) { - //context instance - var self = this; - var args = JSON.parse(JSON.stringify(storageProviderCfg)); - this.storeToken = { - typeName: this.getType().fullName, - args: args, - factory: function () { - return new (self.getType())(args); - } - } - - //set elementType storetoken - var members = this.getType().memberDefinitions.getPublicMappedProperties(); - for (var i = 0; i < members.length; i++) { - var item = members[i]; - if (item.type) { - var itemResolvedDataType = Container.resolveType(item.type); - if (itemResolvedDataType && itemResolvedDataType.isAssignableTo && itemResolvedDataType.isAssignableTo($data.EntitySet)) { - var elementType = Container.resolveType(item.elementType); - if (!elementType.storeToken) { - elementType.storeToken = this.storeToken; - } - } - } - } - - }, - QueryResultModifier: function (query) { - var self = $data.ItemStore; - var context = query.context; - var type = query.modelBinderConfig.$type; - if ('string' === typeof type) { - type = Container.resolveType(type); - } - - if (type === $data.Array && query.modelBinderConfig.$item && query.modelBinderConfig.$item.$type) { - type = query.modelBinderConfig.$item.$type; - } - - //TODO: runs when model binding missed (inmemory) - if ((typeof type === 'undefined' && query.result && query.result[0] instanceof $data.Entity)) { - var navProps = !type ? [] : type.memberDefinitions.getPublicMappedProperties().filter(function (memDef) { - return !!memDef.inverseProperty; - }); - - for (var i = 0; i < query.result.length; i++) { - self._setStoreAlias(query.result[i], context.storeToken); - - for (var j = 0; j < navProps.length; j++) { - var navProp = navProps[j]; - if (query.result[i][navProp.name] instanceof $data.Entity) { - self._setStoreAlias(query.result[i][navProp.name], context.storeToken); - } else if (Array.isArray(query.result[i][navProp.name])) { - for (var k = 0; k < query.result[i][navProp.name].length; k++) { - if (query.result[i][navProp.name][k] instanceof $data.Entity) { - self._setStoreAlias(query.result[i][navProp.name][k], context.storeToken); - } - } - } - } - } - } - } -}); -$data.ItemStore = new $data.ItemStoreClass(); - -$data.Entity.addMember('field', function (propName) { - var def = this.memberDefinitions.getMember(propName); - if (def) { - if (def.definedBy === this) { - return new $data.MemberWrapper(def); - } else { - Guard.raise(new Exception("Member '" + propName + "' defined on '" + def.definedBy.fullName + "'!", 'Invalid Operation')); - } - } else { - Guard.raise(new Exception("Member '" + propName + "' not exists!", 'Invalid Operation')); - } - - return this; -}, true); - - -$data.Class.define('$data.MemberWrapper', null, null, { - constructor: function (memberDefinition) { - this.memberDefinition = memberDefinition; - }, - setKey: function (value) { - this.memberDefinition.key = value || value === undefined ? true : false; - return this; - }, - setComputed: function (value) { - this.memberDefinition.computed = value || value === undefined ? true : false; - return this; - }, - setRequired: function (value) { - this.memberDefinition.required = value || value === undefined ? true : false; - return this; - }, - setNullable: function (value) { - this.memberDefinition.nullable = value || value === undefined ? true : false; - return this; - }, - changeDefinition: function (attr, value) { - this.memberDefinition[attr] = value; - return this; - } -}); - -$data.Class.define('$data.StorageProviderLoaderBase', null, null, { - isSupported: function (providerName) { - $data.Trace.log('Detecting ' + providerName + ' provider support'); - var supported = true; - switch (providerName) { - case 'indexedDb': - supported = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || (window.msIndexedDB && !(/^file:/.test(window.location.href))); - break; - case 'storm': - supported = 'XMLHttpRequest' in window; - break; - case 'webSql': - case 'sqLite': - supported = 'openDatabase' in window; - break; - case 'LocalStore': - supported = 'localStorage' in window && window.localStorage ? true : false; - break; - case 'sqLite': - supported = 'openDatabase' in window; - break; - case 'mongoDB': - supported = $data.mongoDBDriver; - break; - default: - break; - } - $data.Trace.log(providerName + ' provider is ' + (supported ? '' : 'not') + ' supported'); - return supported; - }, - scriptLoadTimeout: { type: 'int', value: 1000 }, - scriptLoadInterval: { type: 'int', value: 50 }, - npmModules: { - value: { - 'indexedDb': 'jaydata-indexeddb', - 'InMemory': 'jaydata-inmemory', - 'LocalStore': 'jaydata-inmemory', - 'mongoDB': 'jaydata-mongodb', - 'oData': 'jaydata-odata', - 'webApi': 'jaydata-webapi', - 'sqLite': 'jaydata-sqlite', - 'webSql': 'jaydata-sqlite', - 'storm': 'jaydata-storm' - } - }, - ProviderNames: { - value: { - 'indexedDb': 'IndexedDb', - 'InMemory': 'InMemory', - 'LocalStore': 'InMemory', - 'oData': 'oData', - 'webApi': 'WebApi', - 'sqLite': 'SqLite', - 'webSql': 'SqLite', - 'storm': 'Storm' - } - }, - load: function (providerList, callback) { - $data.RegisteredStorageProviders = $data.RegisteredStorageProviders || {}; - - $data.Trace.log('Loading provider(s): ' + providerList); - callback = $data.typeSystem.createCallbackSetting(callback); - - var self = this; - var cacheKey = providerList.join(','); - self._fallbackCache = self._fallbackCache || {}; - - if (self._fallbackCache[cacheKey]) { - callback.success(self._fallbackCache[cacheKey]); - } else { - this.find(providerList, { - success: function (provider, selectedProvider) { - self._fallbackCache[cacheKey] = provider; - callback.success.call(this, provider); - }, - error: callback.error - }); - } - }, - find: function (providerList, callback) { - var currentProvider = providerList.shift(); - var currentProvider = this.getVirtual(currentProvider); - if(Array.isArray(currentProvider)){ - providerList = currentProvider; - currentProvider = providerList.shift(); - } - - while (currentProvider && !this.isSupported(currentProvider)) { - currentProvider = providerList.shift(); - } - - $data.Trace.log('First supported provider is ' + currentProvider); - - if (!currentProvider){ - $data.Trace.log('Provider fallback failed'); - callback.error(); - } - - if ($data.RegisteredStorageProviders) { - $data.Trace.log('Is the ' + currentProvider + ' provider already registered?'); - var provider = $data.RegisteredStorageProviders[currentProvider]; - if (provider) { - $data.Trace.log(currentProvider + ' provider registered'); - callback.success(provider) - return; - }else{ - $data.Trace.log(currentProvider + ' provider not registered'); - } - } - - if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { - // NodeJS - $data.Trace.log('node.js detected trying to load NPM module'); - this.loadNpmModule(currentProvider, providerList, callback); - } else { - $data.Trace.log('Browser detected trying to load provider'); - this.loadProvider(currentProvider, providerList, callback); - } - }, - loadProvider: function (currentProvider, providerList, callback) { - var self = this; - var mappedName = $data.StorageProviderLoader.ProviderNames[currentProvider] || currentProvider; - $data.Trace.log(currentProvider + ' provider is mapped to name ' + mappedName + 'Provider'); - if (mappedName) { - var url = this.getUrl(mappedName); - $data.Trace.log(currentProvider + ' provider from URL: ' + url); - - var loader = this.loadScript; - if (document && document.createElement) { - $data.Trace.log('document and document.createElement detected, using script element loader method'); - loader = this.loadScriptElement; - } - - loader.call(this, url, currentProvider, function (successful) { - var provider = $data.RegisteredStorageProviders[currentProvider]; - if (successful && provider) { - $data.Trace.log(currentProvider + ' provider successfully registered'); - callback.success(provider); - } else if (providerList.length > 0) { - $data.Trace.log(currentProvider + ' provider failed to load, trying to fallback to ' + providerList + ' provider(s)'); - self.find(providerList, callback); - } else { - $data.Trace.log(currentProvider + ' provider failed to load'); - callback.error(); - } - }); - } - }, - getUrl: function (providerName) { - var jaydataScriptMin = document.querySelector('script[src$="jaydata.min.js"]'); - var jaydataScript = document.querySelector('script[src$="jaydata.js"]'); - if (jaydataScriptMin) return jaydataScriptMin.src.substring(0, jaydataScriptMin.src.lastIndexOf('/') + 1) + 'jaydataproviders/' + providerName + 'Provider.min.js'; - else if (jaydataScript) return jaydataScript.src.substring(0, jaydataScript.src.lastIndexOf('/') + 1) + 'jaydataproviders/' + providerName + 'Provider.js'; - else return 'jaydataproviders/' + providerName + 'Provider.js'; - }, - loadScript: function (url, currentProvider, callback) { - if (!url){ - callback(false); - return; - } - - function getHttpRequest() { - if (window.XMLHttpRequest) - return new XMLHttpRequest(); - else if (window.ActiveXObject !== undefined) - return new ActiveXObject("MsXml2.XmlHttp"); - else{ - $data.Trace.log('XMLHttpRequest or MsXml2.XmlHttp ActiveXObject not found'); - callback(false); - return; - } - } - - var oXmlHttp = getHttpRequest(); - oXmlHttp.onreadystatechange = function () { - $data.Trace.log('HTTP request is in state: ' + oXmlHttp.readyState); - if (oXmlHttp.readyState == 4) { - if (oXmlHttp.status == 200 || oXmlHttp.status == 304) { - $data.Trace.log('HTTP request succeeded'); - $data.Trace.log('HTTP request response text: ' + oXmlHttp.responseText); - eval.call(window, oXmlHttp.responseText); - if (typeof callback === 'function') - callback(true); - else $data.Trace.log('Callback function is undefined'); - } else { - $data.Trace.log('HTTP request status: ', oXmlHttp.status); - if (typeof callback === 'function') - callback(false); - else $data.Trace.log('Callback function is undefined'); - } - } - }; - oXmlHttp.open('GET', url, true); - oXmlHttp.send(null); - }, - loadScriptElement: function (url, currentProvider, callback) { - var head = document.getElementsByTagName('head')[0] || document.documentElement; - - var script = document.createElement('script'); - script.type = 'text/javascript'; - script.src = url; - $data.Trace.log('Appending child ' + script + ' to ' + head); - head.appendChild(script); - - var loadInterval = this.scriptLoadInterval || 50; - var iteration = Math.ceil(this.scriptLoadTimeout / loadInterval); - $data.Trace.log('Script element watcher iterating ' + iteration + ' times'); - function watcher() { - $data.Trace.log('Script element watcher iteration ' + iteration); - var provider = $data.RegisteredStorageProviders[currentProvider]; - if (provider) { - $data.Trace.log(currentProvider + ' provider registered'); - callback(true); - } else { - iteration--; - if (iteration > 0) { - $data.Trace.log('Script element watcher next iteration'); - setTimeout(watcher, loadInterval); - } else { - $data.Trace.log('Script element loader failed'); - callback(false); - } - } - } - setTimeout(watcher, loadInterval); - }, - - loadNpmModule: function (currentProvider, providerList, callback) { - var provider = null; - try { - require(this.npmModules[currentProvider]); - provider = $data.RegisteredStorageProviders[currentProvider]; - $data.Trace.log('NPM module loader successfully registered ' + currentProvider + ' provider'); - } catch (e) { - $data.Trace.log('NPM module loader failed for ' + currentProvider + ' provider'); - } - - if (provider) { - callback.success(provider); - } else if (providerList.length > 0) { - this.find(providerList, callback); - } else { - callback.error(); - } - }, - - virtualProviders: { - type: $data.Array, - value: { - local: { - fallbacks: ['webSql', 'indexedDb', 'LocalStore'] - } - } - }, - getVirtual: function(name){ - if(this.virtualProviders[name]) - return [].concat(this.virtualProviders[name].fallbacks); - - return name; - } -}); - -$data.StorageProviderLoader = new $data.StorageProviderLoaderBase(); -$data.storageProviders = { - DbCreationType: { - Merge: 10, - DropTableIfChanged: 20, - DropTableIfChange: 20, - DropAllExistingTables: 30, - ErrorIfChange: 40, - DropDbIfChange: 50 - } -} - -$data.ConcurrencyMode = { Fixed: 'fixed', None: 'none' }; -$data.Class.define('$data.StorageProviderBase', null, null, -{ - constructor: function (schemaConfiguration, context) { - this.providerConfiguration = schemaConfiguration || {}; - - this.name = this.getType().name; - if ($data.RegisteredStorageProviders) { - var keys = Object.keys($data.RegisteredStorageProviders); - for (var i = 0; i < keys.length; i++) { - if (this instanceof $data.RegisteredStorageProviders[keys[i]]) { - this.name = keys[i]; - break; - } - } - } - }, - providers: {}, - supportedDataTypes: { value: [], writable: false }, - initializeStore: function (callBack) { - Guard.raise("Pure class"); - }, - - executeQuery: function (queryable, callBack) { - Guard.raise("Pure class"); - }, - loadRawData: function (tableName, callBack) { - callBack = $data.typeSystem.createCallbackSetting(callBack); - callBack.error(new Exception('loadRawData is not supported', 'Invalid Operation')); - }, - - buildIndependentBlocks: function (changedItems) { - /// - /// Build and processes a dependency graph from the changed items, - /// and generates blocks that can be inserted to the database sequentially. - /// - /// Array of changed items to build independent blocks from. - var edgesTo = []; - var edgesFrom = []; - - function hasOwnProperty(obj) { - /// - /// Returns true if object has own property (used for 'hashset'-like objects) - /// - /// Target object - /// True if the object has own property - for (var p in obj) { - if (obj.hasOwnProperty(p)) - return true; - } - return false; - } - - // Building edgesTo and edgesFrom arrays (containing only indeces of items in changedItems array. - for (var i = 0; i < changedItems.length; i++) { - var current = changedItems[i]; - if (!current.dependentOn || current.dependentOn.length == 0) { - // This item is independent - continue; - } - - var to = null; - // Iterating over items 'current' depends on - for (var j = 0; j < current.dependentOn.length; j++) { - var currentDependency = current.dependentOn[j]; - if (currentDependency.entityState == $data.EntityState.Unchanged) { - continue; - } - to = to || {}; - // Getting the index of current dependency - var ixDependendOn = -1; - for (var k = 0; k < changedItems.length; k++) { - if (changedItems[k].data == currentDependency) { - ixDependendOn = k; - break; - } - } - // Sanity check - if (ixDependendOn == -1) { - Guard.raise(new Exception('Dependent object not found', 'ObjectNotFound', current.dependentOn[j])); - } - // Setting edge in 'to' array - to[ixDependendOn] = true; - // Setting edge in 'from' array - from = edgesFrom[ixDependendOn] || {}; - from[i] = true; - edgesFrom[ixDependendOn] = from; - } - // Persisting found edges in edgesTo array - if (to !== null) - edgesTo[i] = to; - } - - // Array of sequentialyl independent blocks (containing objects, not just their id's) - var independentBlocks = []; - // Objects getting their dependency resolved in the current cycle. - var currentBlock = []; - // Filling currentBlock with initially independent objects. - for (var x = 0; x < changedItems.length; x++) { - if (!edgesTo.hasOwnProperty(x)) { - currentBlock.push(x); - } - } - while (currentBlock.length > 0) { - // Shifting currentBlock to cbix, - // and clearing currentBlock for next independent block - var cbix = [].concat(currentBlock); - currentBlock = []; - // Iterating over previous independent block, to generate the new one - for (var b = 0; b < cbix.length; b++) { - var dependentNodes = edgesFrom[cbix[b]]; - if (typeof dependentNodes !== 'undefined') { - for (var d in dependentNodes) { - // Removing edge from 'edgesTo' - delete edgesTo[d][cbix[b]]; - // Check if has any more dependency - if (!hasOwnProperty(edgesTo[d])) { - // It doesn't, so let's clean up a bit - delete edgesTo[d]; - // and push the item to 'currentBlock' - currentBlock.push(d); - } - } - } - // Clearing processed item from 'edgesFrom' - delete edgesFrom[cbix[b]]; - } - // Push cbix t to independentBlocks - var cb = []; - for (var c = 0; c < cbix.length; c++) { - var item = changedItems[cbix[c]]; - if (item.data.entityState != $data.EntityState.Unchanged) - cb.push(item); - } - if (cb.length > 0) - independentBlocks.push(cb); - } - return independentBlocks; - }, - getTraceString: function (queryable) { - Guard.raise("Pure class"); - }, - setContext: function (ctx) { - this.context = ctx; - }, - - _buildContinuationFunction: function (context, query) { - if (Array.isArray(query.result)) { - query.result.next = this._buildPagingMethod(context, query, 'next'); - query.result.prev = this._buildPagingMethod(context, query, 'prev'); - } - }, - _buildPagingMethod: function (context, query, mode) { - return function (onResult_items) { - var pHandler = new $data.PromiseHandler(); - var cbWrapper = pHandler.createCallback(onResult_items); - - var continuation = new $data.Expressions.ContinuationExpressionBuilder(mode); - var continuationResult = continuation.compile(query); - if (continuationResult.expression) { - var queryable = Container.createQueryable(context, continuationResult.expression); - queryable.defaultType = query.defaultType; - context.executeQuery(queryable, cbWrapper); - } else { - cbWrapper.error(new Exception(continuationResult.message, 'Invalid Operation', continuationResult)); - } - - return pHandler.getPromise(); - } - }, - - buildDbType_modifyInstanceDefinition: function (instanceDefinition, storageModel) { - var buildDbType_copyPropertyDefinition = function (propertyDefinition, refProp) { - var cPropertyDef; - if (refProp) { - cPropertyDef = JSON.parse(JSON.stringify(instanceDefinition[refProp])); - cPropertyDef.kind = propertyDefinition.kind; - cPropertyDef.name = propertyDefinition.name; - cPropertyDef.notMapped = false; - } else { - cPropertyDef = JSON.parse(JSON.stringify(propertyDefinition)); - } - - cPropertyDef.dataType = Container.resolveType(propertyDefinition.dataType); - cPropertyDef.type = cPropertyDef.dataType; - cPropertyDef.key = false; - cPropertyDef.computed = false; - return cPropertyDef; - }; - var buildDbType_createConstrain = function (foreignType, dataType, propertyName, prefix, keyPropertyName) { - var constrain = new Object(); - constrain[foreignType.name] = propertyName; - constrain[dataType.name] = keyPropertyName ? keyPropertyName : prefix + '__' + propertyName; - return constrain; - }; - - if (storageModel.Associations) { - storageModel.Associations.forEach(function (association) { - var addToEntityDef = false; - var foreignType = association.FromType; - var dataType = association.ToType; - var foreignPropName = association.ToPropertyName; - - var memDef = association.FromType.getMemberDefinition(association.FromPropertyName); - var keyProperties = []; - if (memDef && typeof memDef.keys === "string" && memDef.keys) { - keyProperties = [memDef.keys]; - } else if (memDef && Array.isArray(memDef.keys)) { - keyProperties = [].concat(memDef.keys); - } - - association.ReferentialConstraint = association.ReferentialConstraint || []; - - if ((association.FromMultiplicity == "*" && association.ToMultiplicity == "0..1") || (association.FromMultiplicity == "0..1" && association.ToMultiplicity == "1")) { - foreignType = association.ToType; - dataType = association.FromType; - foreignPropName = association.FromPropertyName; - addToEntityDef = true; - } - - foreignType.memberDefinitions.getPublicMappedProperties().filter(function (d) { return d.key }).forEach(function (d, i) { - var constraint = buildDbType_createConstrain(foreignType, dataType, d.name, foreignPropName, keyProperties[i]); - if (addToEntityDef) { - //instanceDefinition[foreignPropName + '__' + d.name] = buildDbType_copyPropertyDefinition(d, foreignPropName); - instanceDefinition[constraint[dataType.name]] = buildDbType_copyPropertyDefinition(d, foreignPropName); - - var dependentMemDef = dataType.getMemberDefinition(keyProperties[i]); - if (dependentMemDef) { - dependentMemDef.isDependentProperty = true; - dependentMemDef.navigationPropertyName = association.FromPropertyName; - } - } - association.ReferentialConstraint.push(constraint); - }, this); - }, this); - } - //Copy complex type properties - if (storageModel.ComplexTypes) { - storageModel.ComplexTypes.forEach(function (complexType) { - complexType.ReferentialConstraint = complexType.ReferentialConstraint || []; - - complexType.ToType.memberDefinitions.getPublicMappedProperties().forEach(function (d) { - instanceDefinition[complexType.FromPropertyName + '__' + d.name] = buildDbType_copyPropertyDefinition(d); - complexType.ReferentialConstraint.push(buildDbType_createConstrain(complexType.ToType, complexType.FromType, d.name, complexType.FromPropertyName)); - }, this); - }, this); - } - }, - buildDbType_generateConvertToFunction: function (storageModel) { - return function (logicalEntity) { - var dbInstance = new storageModel.PhysicalType(); - dbInstance.entityState = logicalEntity.entityState; - - //logicalEntity.changedProperties.forEach(function(memberDef){ - //}, this); - storageModel.PhysicalType.memberDefinitions.getPublicMappedProperties().forEach(function (property) { - if (logicalEntity[property.name] !== undefined) { - dbInstance[property.name] = logicalEntity[property.name]; - } - }, this); - - if (storageModel.Associations) { - storageModel.Associations.forEach(function (association) { - if ((association.FromMultiplicity == "*" && association.ToMultiplicity == "0..1") || (association.FromMultiplicity == "0..1" && association.ToMultiplicity == "1")) { - var complexInstance = logicalEntity[association.FromPropertyName]; - if (complexInstance !== undefined) { - association.ReferentialConstraint.forEach(function (constrain) { - if (complexInstance !== null) { - dbInstance[constrain[association.From]] = complexInstance[constrain[association.To]]; - } else { - dbInstance[constrain[association.From]] = null; - } - }, this); - } - } - }, this); - } - if (storageModel.ComplexTypes) { - storageModel.ComplexTypes.forEach(function (cmpType) { - var complexInstance = logicalEntity[cmpType.FromPropertyName]; - if (complexInstance !== undefined) { - cmpType.ReferentialConstraint.forEach(function (constrain) { - if (complexInstance !== null) { - dbInstance[constrain[cmpType.From]] = complexInstance[constrain[cmpType.To]]; - } else { - dbInstance[constrain[cmpType.From]] = null; - } - }, this); - } - }, this); - } - return dbInstance; - }; - }, - - bulkInsert: function (a, b, c, callback) { - callback.error(new Exception('Not Implemented')); - }, - - supportedFieldOperations: { - value: { - length: { dataType: "number", allowedIn: "filter, map" }, - substr: { dataType: "string", allowedIn: "filter", parameters: [{ name: "startFrom", dataType: "number" }, { name: "length", dataType: "number" }] }, - toLowerCase: { dataType: "string" } - }, - enumerable: true, - writable: true - }, - - resolveFieldOperation: function (operationName, expression, frameType) { - /// - var result = this.supportedFieldOperations[operationName]; - if (Array.isArray(result)) { - var i = 0; - for (; i < result.length; i++) { - if (result[i].allowedType === 'default' || Container.resolveType(result[i].allowedType) === Container.resolveType(expression.selector.memberDefinition.type) && - (frameType && result[i].allowedIn && - ( - (Array.isArray(result[i].allowedIn) && result[i].allowedIn.some(function(type){ return frameType === Container.resolveType(type); })) || - (!Array.isArray(result[i].allowedIn) && (frameType === Container.resolveType(result[i].allowedIn))) - ) - ) - ) { - result = result[i]; - break; - } - } - if (i === result.length) { - result = undefined; - } - } - - if (!result) { - Guard.raise(new Exception("Field operation '" + operationName + "' is not supported by the provider")); - }; - if (frameType && result.allowedIn) { - if ((result.allowedIn instanceof Array && !result.allowedIn.some(function (type) { return frameType === Container.resolveType(type); })) || - (!(result.allowedIn instanceof Array) && frameType !== Container.resolveType(result.allowedIn))) { - Guard.raise(new Exception(operationName + " not supported in: " + frameType.name)); - } - } - result.name = operationName; - return result; - }, - - supportedBinaryOperators: { - value: { - equal: { mapTo: 'eq', dataType: "boolean" } - }, - enumerable: true, - writable: true - }, - - resolveBinaryOperator: function (operator, expression, frameType) { - var result = this.supportedBinaryOperators[operator]; - if (!result) { - Guard.raise(new Exception("Binary operator '" + operator + "' is not supported by the provider")); - }; - if (frameType && result.allowedIn) { - if ((result.allowedIn instanceof Array && !result.allowedIn.some(function (type) { return frameType === Container.resolveType(type); })) || - (!(result.allowedIn instanceof Array) && frameType !== Container.resolveType(result.allowedIn))) { - Guard.raise(new Exception(operator + " not supported in: " + frameType.name)); - } - } - result.name = operator; - return result; - }, - - supportedUnaryOperators: { - value: { - not: { mapTo: 'not' } - }, - enumerable: true, - writable: true - }, - resolveUnaryOperator: function (operator, expression, frameType) { - var result = this.supportedUnaryOperators[operator]; - if (!result) { - Guard.raise(new Exception("Unary operator '" + operator + "' is not supported by the provider")); - }; - if (frameType && result.allowedIn) { - if ((result.allowedIn instanceof Array && !result.allowedIn.some(function (type) { return frameType === Container.resolveType(type); })) || - (!(result.allowedIn instanceof Array) && frameType !== Container.resolveType(result.allowedIn))) { - Guard.raise(new Exception(operator + " not supported in: " + frameType.name)); - } - } - result.name = operator; - return result; - }, - - supportedSetOperations: { - value: { - toArray: { invokable: true, allowedIn: [] } - }, - enumerable: true, - writable: true - }, - resolveSetOperations: function (operation, expression, frameType) { - var result = this.supportedSetOperations[operation]; - if (!result) { - Guard.raise(new Exception("Operation '" + operation + "' is not supported by the provider")); - }; - var allowedIn = result.allowedIn || []; - if (frameType && allowedIn) { - if ((allowedIn instanceof Array && !allowedIn.some(function (type) { return frameType === Container.resolveType(type); })) || - (!(allowedIn instanceof Array) && frameType !== Container.resolveType(allowedIn))) { - Guard.raise(new Exception(operation + " not supported in: " + frameType.name)); - } - } - return result; - }, - - resolveTypeOperations: function (operation, expression, frameType) { - Guard.raise(new Exception("Entity '" + expression.entityType.name + "' Operation '" + operation + "' is not supported by the provider")); - }, - - resolveContextOperations: function (operation, expression, frameType) { - Guard.raise(new Exception("Context '" + expression.instance.getType().name + "' Operation '" + operation + "' is not supported by the provider")); - }, - - makePhysicalTypeDefinition: function (entityDefinition, association) { - }, - - _beginTran: function (tables, isWrite, callBack) { - callBack.success(new $data.Transaction()); - }, - - getFieldUrl: function () { - return '#'; - }, - - supportedAutoincrementKeys: { - value: { } - } -}, -{ - onRegisterProvider: { value: new $data.Event() }, - registerProvider: function (name, provider) { - this.onRegisterProvider.fire({ name: name, provider: provider }, this); - $data.RegisteredStorageProviders = $data.RegisteredStorageProviders || []; - $data.RegisteredStorageProviders[name] = provider; - }, - getProvider: function (name) { - var provider = $data.RegisteredStorageProviders[name]; - if (!provider) - console.warn("Provider not found: '" + name + "'"); - return provider; - /*var provider = $data.RegisteredStorageProviders[name]; - if (!provider) - Guard.raise(new Exception("Provider not found: '" + name + "'", "Not Found")); - return provider;*/ - }, - isSupported: { - get: function () { return true; }, - set: function () { } - } -}); -$data.Class.define('$data.ServiceOperation', null, null, {}, { - translateDefinition: function (propertyDef, name, definedBy) { - propertyDef.serviceName = name; - var memDef = new $data.MemberDefinition(this.generateServiceOperation(propertyDef), this); - memDef.name = name; - return memDef; - }, - generateServiceOperation: function (cfg) { - - var fn; - if (cfg.serviceMethod) { - var returnType = cfg.returnType ? Container.resolveType(cfg.returnType) : {}; - if (returnType.isAssignableTo && returnType.isAssignableTo($data.Queryable)) { - fn = cfg.serviceMethod; - } else { - fn = function () { - var lastParam = arguments[arguments.length - 1]; - - var pHandler = new $data.PromiseHandler(); - var cbWrapper; - - var args = arguments; - if (typeof lastParam === 'function') { - cbWrapper = pHandler.createCallback(lastParam); - arguments[arguments.length - 1] = cbWrapper; - } else { - cbWrapper = pHandler.createCallback(); - arguments.push(cbWrapper); - } - - try { - var result = cfg.serviceMethod.apply(this, arguments); - if (result !== undefined) - cbWrapper.success(result); - } catch (e) { - cbWrapper.error(e); - } - - return pHandler.getPromise(); - } - } - - } else { - fn = function () { - var context = this; - var memberdef; - - var boundItem; - if (this instanceof $data.Entity || this instanceof $data.EntitySet) { - var entitySet; - if (this instanceof $data.Entity) { - if (this.context) { - context = this.context; - entitySet = context.getEntitySetFromElementType(this.getType()); - } else if (this.storeToken && typeof this.storeToken.factory === 'function') { - context = this.storeToken.factory(); - entitySet = context.getEntitySetFromElementType(this.getType()); - } else { - Guard.raise(new Exception("entity can't resolve context", 'Not Found!', this)); - return; - } - } else if (this instanceof $data.EntitySet) { - context = this.entityContext; - entitySet = this; - - var esDef = context.getType().getMemberDefinition(entitySet.name); - memberdef = $data.MemberDefinition.translateDefinition(esDef.actions[cfg.serviceName], cfg.serviceName, entitySet.getType()); - } - - - boundItem = { - data: this, - entitySet: entitySet - }; - } - - var virtualEntitySet = cfg.elementType ? context.getEntitySetFromElementType(Container.resolveType(cfg.elementType)) : null; - - var paramConstExpression = null; - if (cfg.params) { - paramConstExpression = []; - //object as parameter - if (arguments[0] && typeof arguments[0] === 'object' && arguments[0].constructor === $data.Object && cfg.params && cfg.params[0] && cfg.params[0].name in arguments[0]) { - var argObj = arguments[0]; - for (var i = 0; i < cfg.params.length; i++) { - var paramConfig = cfg.params[i]; - if (paramConfig.name && paramConfig.type && paramConfig.name in argObj) { - paramConstExpression.push(Container.createConstantExpression(argObj[paramConfig.name], Container.resolveType(paramConfig.type), paramConfig.name)); - } - } - } - //arg params - else { - for (var i = 0; i < cfg.params.length; i++) { - if (typeof arguments[i] == 'function') break; - - //TODO: check params type - var paramConfig = cfg.params[i]; - if (paramConfig.name && paramConfig.type && arguments[i] !== undefined) { - paramConstExpression.push(Container.createConstantExpression(arguments[i], Container.resolveType(paramConfig.type), paramConfig.name)); - } - } - } - } - - var ec = Container.createEntityContextExpression(context); - if (!memberdef) { - if (boundItem && boundItem.data) { - memberdef = boundItem.data.getType().getMemberDefinition(cfg.serviceName); - } else { - memberdef = context.getType().getMemberDefinition(cfg.serviceName); - } - } - var es = Container.createServiceOperationExpression(ec, - Container.createMemberInfoExpression(memberdef), - paramConstExpression, - cfg, - boundItem); - - //Get callback function - var clb = arguments[arguments.length - 1]; - if (!(typeof clb === 'function' || (typeof clb === 'object' /*&& clb.constructor === $data.Object*/ && (typeof clb.success === 'function' || typeof clb.error === 'function')))) { - clb = undefined; - } - - if (virtualEntitySet) { - var q = Container.createQueryable(virtualEntitySet, es); - if (clb) { - es.isTerminated = true; - return q._runQuery(clb); - } - return q; - } - else { - var returnType = cfg.returnType ? Container.resolveType(cfg.returnType) : null; - - var q = Container.createQueryable(context, es); - q.defaultType = returnType || $data.Object; - - if (returnType === $data.Queryable) { - q.defaultType = Container.resolveType(cfg.elementType); - if (clb) { - es.isTerminated = true; - return q._runQuery(clb); - } - return q; - } - es.isTerminated = true; - return q._runQuery(clb); - } - }; - }; - - var params = cfg.params || []; - $data.typeSystem.extend(fn, cfg, { params: params }); - - return fn; - } -}); - -$data.Class.define('$data.ServiceAction', $data.ServiceOperation, null, {}, { - generateServiceOperation: function (cfg) { - if (!cfg.method) { - cfg.method = 'POST'; //default Action method is POST - } - - return $data.ServiceOperation.generateServiceOperation.apply(this, arguments); - } -});$data.Base.extend('$data.EntityWrapper', { - getEntity: function () { - Guard.raise("pure object"); - } -}); -if (typeof jQuery !== 'undefined' && jQuery.ajax) { - $data.ajax = $data.ajax || jQuery.ajax; -} - -if (typeof WinJS !== 'undefined' && WinJS.xhr) { - $data.ajax = $data.ajax || function (options) { - $data.typeSystem.extend(options, { - dataType: 'json', - headers: {} - }); - var dataTypes = { - 'json': { - accept: 'application/json, text/javascript', - convert: JSON.parse - }, - 'text': { - accept: 'text/plain', - convert: function (e) { return e; } - }, - 'html': { - accept: 'text/html', - convert: function (e) { return e; } - }, - 'xml': { - accept: 'application/xml, text/xml', - convert: function (e) { - // TODO? - return e; - } - } - } - var dataTypeContext = dataTypes[options.dataType.toLowerCase()]; - - options.headers.Accept = dataTypeContext.accept; - - var successClb = options.success || $data.defaultSuccessCallback; - var errorClb = options.error || $data.defaultErrorCallback; - var progressClb = options.progress; - - var success = function (r) { - var result = dataTypeContext.convert(r.responseText); - successClb(result); - } - var error = function (r) { - var error = dataTypeContext.convert(r.responseText); - errorClb(error); - } - var progress = progressClb; - - WinJS.xhr(options) - .done(success, error, progress); - } -} - -if (typeof Ext !== 'undefined' && typeof Ext.Ajax) { - $data.ajax = $data.ajax || function (options) { - Ext.Ajax.request(options); - }; -} - -$data.ajax = $data.ajax || function () { - var cfg = arguments[arguments.length - 1]; - var clb = $data.typeSystem.createCallbackSetting(cfg); - clb.error("Not implemented"); -}; - - -$C('$data.modelBinder.FindProjectionVisitor', $data.Expressions.EntityExpressionVisitor, null, { - VisitProjectionExpression: function (expression) { - this.projectionExpression = expression; - } -}); - -$C('$data.modelBinder.ModelBinderConfigCompiler', $data.Expressions.EntityExpressionVisitor, null, { - constructor: function (query, includes, oDataProvider) { - this._query = query; - this._includes = includes; - this._isoDataProvider = oDataProvider || false; - }, - VisitSingleExpression: function (expression) { - this._defaultModelBinder(expression); - }, - VisitSomeExpression: function (expression) { - this._defaultModelBinder(expression); - }, - VisitFindExpression: function (expression) { - this._defaultModelBinder(expression); - }, - VisitEveryExpression: function (expression) { - this._defaultModelBinder(expression); - }, - VisitToArrayExpression: function (expression) { - this._defaultModelBinder(expression); - }, - VisitFirstExpression: function (expression) { - this._defaultModelBinder(expression); - }, - VisitForEachExpression: function (expression) { - this._defaultModelBinder(expression); - }, - VisitServiceOperationExpression: function (expression) { - if (expression.cfg.returnType) { - var returnType = Container.resolveType(expression.cfg.returnType); - if ((typeof returnType.isAssignableTo === 'function' && returnType.isAssignableTo($data.Queryable)) || returnType === $data.Array) { - this._defaultModelBinder(expression); - } else { - var builder = Container.createqueryBuilder(); - builder.modelBinderConfig['$type'] = returnType; - if (typeof returnType.isAssignableTo === 'function' && returnType.isAssignableTo($data.Entity)) { - builder.modelBinderConfig['$selector'] = ['json:' + expression.cfg.serviceName]; - } else { - builder.modelBinderConfig['$type'] = returnType; - builder.modelBinderConfig['$value'] = function (a, v) { - return (expression.cfg.serviceName in v) ? v[expression.cfg.serviceName] : v.value; - } - } - this.VisitExpression(expression, builder); - builder.resetModelBinderProperty(); - this._query.modelBinderConfig = builder.modelBinderConfig; - } - } - }, - VisitCountExpression: function (expression) { - var builder = Container.createqueryBuilder(); - - builder.modelBinderConfig['$type'] = $data.Array; - builder.selectModelBinderProperty('$item'); - builder.modelBinderConfig['$type'] = $data.Integer; - builder.modelBinderConfig['$source'] = 'cnt'; - builder.resetModelBinderProperty(); - this._query.modelBinderConfig = builder.modelBinderConfig; - }, - VisitBatchDeleteExpression: function (expression) { - var builder = Container.createqueryBuilder(); - - builder.modelBinderConfig['$type'] = $data.Array; - builder.selectModelBinderProperty('$item'); - builder.modelBinderConfig['$type'] = $data.Integer; - builder.modelBinderConfig['$source'] = 'cnt'; - builder.resetModelBinderProperty(); - this._query.modelBinderConfig = builder.modelBinderConfig; - }, - VisitConstantExpression: function (expression, builder) { - builder.modelBinderConfig['$type'] = expression.type; - builder.modelBinderConfig['$value'] = expression.value; - }, - - VisitExpression: function (expression, builder) { - var projVisitor = Container.createFindProjectionVisitor(); - projVisitor.Visit(expression); - - if (projVisitor.projectionExpression) { - this.Visit(projVisitor.projectionExpression, builder); - } else { - this.DefaultSelection(builder, this._query.defaultType, this._includes); - } - }, - _defaultModelBinder: function (expression) { - var builder = Container.createqueryBuilder(); - builder.modelBinderConfig['$type'] = $data.Array; - if (this._isoDataProvider) { - builder.modelBinderConfig['$selector'] = ['json:d.results', 'json:d', 'json:results']; - } - builder.modelBinderConfig['$item'] = {}; - builder.selectModelBinderProperty('$item'); - - this.VisitExpression(expression, builder); - - builder.resetModelBinderProperty(); - this._query.modelBinderConfig = builder.modelBinderConfig; - }, - _addPropertyToModelBinderConfig: function (elementType, builder) { - var storageModel = this._query.context._storageModel.getStorageModel(elementType); - if (elementType.memberDefinitions) { - elementType.memberDefinitions.getPublicMappedProperties().forEach(function (prop) { - if ((!storageModel) || (storageModel && !storageModel.Associations[prop.name] && !storageModel.ComplexTypes[prop.name])) { - - var type = Container.resolveType(prop.dataType); - if (!storageModel && this._query.context.storageProvider.supportedDataTypes.indexOf(type) < 0) { - //complex type - builder.selectModelBinderProperty(prop.name); - builder.modelBinderConfig['$type'] = type; - if (this._isoDataProvider) { - builder.modelBinderConfig['$selector'] = ['json:' + prop.name + '.results', 'json:' + prop.name]; - } else { - builder.modelBinderConfig['$selector'] = 'json:' + prop.name; - } - this._addPropertyToModelBinderConfig(type, builder); - builder.popModelBinderProperty(); - } else { - if (prop.key) { - builder.addKeyField(prop.name); - } - if (prop.concurrencyMode === $data.ConcurrencyMode.Fixed) { - builder.modelBinderConfig[prop.name] = { $selector: 'json:__metadata', $source: 'etag' } - } else if (type === $data.Array && prop.elementType) { - builder.selectModelBinderProperty(prop.name); - builder.modelBinderConfig['$type'] = type; - if (this._isoDataProvider) { - builder.modelBinderConfig['$selector'] = ['json:' + prop.name + '.results', 'json:' + prop.name]; - } else { - builder.modelBinderConfig['$selector'] = 'json:' + prop.name; - } - builder.selectModelBinderProperty('$item'); - var arrayElementType = Container.resolveType(prop.elementType); - builder.modelBinderConfig['$type'] = arrayElementType; - this._addPropertyToModelBinderConfig(arrayElementType, builder); - builder.popModelBinderProperty(); - builder.popModelBinderProperty(); - } else { - builder.modelBinderConfig[prop.name] = prop.name; - } - } - } - }, this); - } else { - /*builder._binderConfig = { - $selector: ['json:results'], - $type: $data.Array, - $item:{ - $type: elementType, - $value: function (meta, data) { return data; } - } - }*/ - builder._binderConfig.$item = builder._binderConfig.$item || {}; - builder.modelBinderConfig = builder._binderConfig.$item; - - - - } - if (storageModel) { - this._addComplexTypeProperties(storageModel.ComplexTypes, builder); - } - }, - _addComplexTypeProperties: function (complexTypes, builder) { - complexTypes.forEach(function (ct) { - if (ct.ToType !== $data.Array){ - builder.selectModelBinderProperty(ct.FromPropertyName); - builder.modelBinderConfig['$type'] = ct.ToType; - if (this._isoDataProvider) { - builder.modelBinderConfig['$selector'] = ['json:' + ct.FromPropertyName + '.results', 'json:' + ct.FromPropertyName]; - } else { - builder.modelBinderConfig['$selector'] = 'json:' + ct.FromPropertyName; - } - this._addPropertyToModelBinderConfig(ct.ToType, builder); - - builder.popModelBinderProperty(); - }else{ - var dt = ct.ToType; - var et = Container.resolveType(ct.FromType.memberDefinitions.getMember(ct.FromPropertyName).elementType); - if (dt === $data.Array && et && et.isAssignableTo && et.isAssignableTo($data.Entity)){ - config = { - $type: $data.Array, - $selector: 'json:' + ct.FromPropertyName, - $item: { - $type: et - } - }; - var md = et.memberDefinitions.getPublicMappedProperties(); - for (var i = 0; i < md.length; i++){ - config.$item[md[i].name] = { $type: md[i].type, $source: md[i].name }; - } - builder.modelBinderConfig[ct.FromPropertyName] = config; - }else{ - builder.modelBinderConfig[ct.FromPropertyName] = { - $type: ct.ToType, - $source: ct.FromPropertyName - }; - } - } - }, this); - }, - DefaultSelection: function (builder, type, allIncludes) { - //no projection, get all item from entitySet - builder.modelBinderConfig['$type'] = type; - - var storageModel = this._query.context._storageModel.getStorageModel(type); - this._addPropertyToModelBinderConfig(type, builder); - if (allIncludes) { - allIncludes.forEach(function (include) { - var includes = include.name.split('.'); - var association = null; - var tmpStorageModel = storageModel; - var itemCount = 0; - for (var i = 0; i < includes.length; i++) { - if (builder.modelBinderConfig.$item) { - builder.selectModelBinderProperty('$item'); - itemCount++; - } - builder.selectModelBinderProperty(includes[i]); - association = tmpStorageModel.Associations[includes[i]]; - tmpStorageModel = this._query.context._storageModel.getStorageModel(association.ToType); - } - if (this._isoDataProvider) { - builder.modelBinderConfig['$selector'] = ['json:' + includes[includes.length - 1] + '.results', 'json:' + includes[includes.length - 1]]; - } else { - builder.modelBinderConfig['$selector'] = 'json:' + includes[includes.length - 1]; - } - if (association.ToMultiplicity === '*') { - builder.modelBinderConfig['$type'] = $data.Array; - builder.selectModelBinderProperty('$item'); - builder.modelBinderConfig['$type'] = include.type; - this._addPropertyToModelBinderConfig(include.type, builder); - builder.popModelBinderProperty(); - } else { - builder.modelBinderConfig['$type'] = include.type; - this._addPropertyToModelBinderConfig(include.type, builder); - } - - for (var i = 0; i < includes.length + itemCount; i++) { - builder.popModelBinderProperty(); - } - }, this); - } - }, - VisitProjectionExpression: function (expression, builder) { - this.hasProjection = true; - this.Visit(expression.selector, builder); - - if (expression.selector && expression.selector.expression instanceof $data.Expressions.ObjectLiteralExpression) { - builder.modelBinderConfig['$type'] = expression.projectionAs || builder.modelBinderConfig['$type'] || $data.Object; - } - }, - VisitParametricQueryExpression: function (expression, builder) { - if (expression.expression instanceof $data.Expressions.EntityExpression || expression.expression instanceof $data.Expressions.EntitySetExpression) { - this.VisitEntityAsProjection(expression, builder); - } else { - this.Visit(expression.expression, builder); - } - - }, - VisitEntityAsProjection: function (expression, builder) { - this.mapping = ''; - this.Visit(expression.expression, builder); - var includes; - if (this.mapping && this._includes instanceof Array) { - includes = this._includes.filter(function (inc) { - return inc.name.indexOf(this.mapping + '.') === 0 - }, this); - includes = includes.map(function (inc) { - return { name: inc.name.replace(this.mapping + '.', ''), type: inc.type }; - }, this); - - if (includes.length > 0){ - this.DefaultSelection(builder, expression.expression.entityType, includes); - //console.warn('WARN: include for mapped properties is not supported!'); - } - } - - if (expression.expression instanceof $data.Expressions.EntityExpression) { - this.DefaultSelection(builder, expression.expression.entityType/*, includes*/) - } else if (expression.expression instanceof $data.Expressions.EntitySetExpression) { - builder.modelBinderConfig.$type = $data.Array; - builder.modelBinderConfig.$item = {}; - builder.selectModelBinderProperty('$item'); - this.DefaultSelection(builder, expression.expression.elementType /*, includes*/) - builder.popModelBinderProperty(); - } - - }, - - VisitEntityFieldExpression: function (expression, builder) { - this.Visit(expression.source, builder); - this.Visit(expression.selector, builder); - }, - VisitMemberInfoExpression: function (expression, builder) { - builder.modelBinderConfig['$type'] = expression.memberDefinition.type; - if (expression.memberDefinition.storageModel && expression.memberName in expression.memberDefinition.storageModel.ComplexTypes) { - this._addPropertyToModelBinderConfig(Container.resolveType(expression.memberDefinition.type), builder); - } else { - if (!(builder.modelBinderConfig.$type && Container.resolveType(builder.modelBinderConfig.$type).isAssignableTo && Container.resolveType(builder.modelBinderConfig.$type).isAssignableTo($data.Entity))) - builder.modelBinderConfig['$source'] = expression.memberName; - } - }, - VisitEntitySetExpression: function (expression, builder) { - if (expression.source instanceof $data.Expressions.EntityExpression) { - this.Visit(expression.source, builder); - this.Visit(expression.selector, builder); - } - - }, - VisitComplexTypeExpression: function (expression, builder) { - this.Visit(expression.source, builder); - this.Visit(expression.selector, builder); - - - if (('$selector' in builder.modelBinderConfig) && (builder.modelBinderConfig.$selector.length > 0)) { - if (builder.modelBinderConfig.$selector instanceof $data.Array) { - var temp = builder.modelBinderConfig.$selector[1]; - builder.modelBinderConfig.$selector[0] = temp + '.' + expression.selector.memberName + '.results'; - builder.modelBinderConfig.$selector[1] = temp + '.' + expression.selector.memberName; - } else { - builder.modelBinderConfig.$selector += '.' + expression.selector.memberName; - } - - } else { - if (this._isoDataProvider) { - builder.modelBinderConfig['$selector'] = ['json:' + expression.selector.memberName + '.results', 'json:' + expression.selector.memberName]; - } else { - builder.modelBinderConfig['$selector'] = 'json:' + expression.selector.memberName; - } - } - }, - VisitEntityExpression: function (expression, builder) { - this.Visit(expression.source, builder); - }, - VisitAssociationInfoExpression: function (expression, builder) { - if (('$selector' in builder.modelBinderConfig) && (builder.modelBinderConfig.$selector.length > 0)) { - if (builder.modelBinderConfig.$selector instanceof $data.Array) { - var temp = builder.modelBinderConfig.$selector[1]; - builder.modelBinderConfig.$selector[0] = temp + '.' + expression.associationInfo.FromPropertyName + '.results'; - builder.modelBinderConfig.$selector[1] = temp + '.' + expression.associationInfo.FromPropertyName; - } else { - builder.modelBinderConfig.$selector += '.' + expression.associationInfo.FromPropertyName; - } - - } else { - if (this._isoDataProvider) { - builder.modelBinderConfig['$selector'] = ['json:' + expression.associationInfo.FromPropertyName + '.results', 'json:' + expression.associationInfo.FromPropertyName]; - } else { - builder.modelBinderConfig['$selector'] = 'json:' + expression.associationInfo.FromPropertyName; - } - } - - if (this.mapping && this.mapping.length > 0) { this.mapping += '.'; } - this.mapping += expression.associationInfo.FromPropertyName; - }, - VisitObjectLiteralExpression: function (expression, builder) { - builder.modelBinderConfig['$type'] = $data.Object; - expression.members.forEach(function (of) { - this.Visit(of, builder); - }, this); - }, - VisitObjectFieldExpression: function (expression, builder) { - builder.selectModelBinderProperty(expression.fieldName); - if (expression.expression instanceof $data.Expressions.EntityExpression || expression.expression instanceof $data.Expressions.EntitySetExpression) { - this.VisitEntityAsProjection(expression, builder); - } else { - this.Visit(expression.expression, builder); - } - builder.popModelBinderProperty(); - } -}); -$data.Class.define("$data.Authentication.AuthenticationBase", null, null, { - constructor: function (cfg) { - this.configuration = cfg || {}; - this.Authenticated = false; - }, - /// { error:, abort:, pending:, success: } - Login: function (callbacks) { - Guard.raise("Pure class"); - }, - Logout: function () { - Guard.raise("Pure class"); - }, - CreateRequest: function (cfg) { - Guard.raise("Pure class"); - } - -}, null);$data.Class.define("$data.Authentication.Anonymous", $data.Authentication.AuthenticationBase, null, { - constructor: function (cfg) { - this.configuration = cfg || {}; - this.Authenticated = false; - }, - /// { error:, abort:, pending:, success: } - Login: function (callbacks) { - }, - Logout: function () { - }, - CreateRequest: function (cfg) { - $data.ajax(cfg); - } - -}, null);$data.Class.define("$data.Authentication.FacebookAuth", $data.Authentication.AuthenticationBase, null, { - constructor: function (cfg) { - this.configuration = $data.typeSystem.extend({ - Url_code: '', - type_code: '', - scope: '', - Url_token: '', - type_token: '', - access_token: '', - app_id: '' - }, cfg); - }, - Login: function (callbacks) { - if (this.Authenticated) { - return; - } - - var provider = this; - provider.configuration.stateCallbacks = callbacks || {}; - - $data.ajax({ - url: this.configuration.Url_code, - data: 'type=' + provider.configuration.type_code + '&client_id=' + provider.configuration.app_id + '&scope=' + provider.configuration.scope, - type: 'POST', - dataType: 'json', - success: function (data) { - if (typeof provider.configuration.stateCallbacks.pending == "function") - provider.configuration.stateCallbacks.pending(data); - provider._processRequestToken(data); - provider.Authenticated = true; - }, - error: function () { - if (typeof provider.configuration.stateCallbacks.error == "function") - provider.configuration.stateCallbacks.error(arguments); - } - }); - }, - Logout: function () { - this.Authenticated = false; - }, - CreateRequest: function (cfg) { - if (!cfg) - return; - var _this = this; - - if (cfg.url.indexOf('access_token=') === -1) { - if (cfg.url && this.Authenticated) { - var andChar = '?'; - if (cfg.url.indexOf(andChar) > 0) - andChar = '&'; - - if (this.configuration.access_token) - cfg.url = cfg.url + andChar + 'access_token=' + this.configuration.access_token; - } - } - - $data.ajax(cfg); - }, - _processRequestToken: function (verification_data) { - var provider = this; - - $data.ajax({ - url: provider.configuration.Url_token, - data: 'type=' + provider.configuration.type_token + '&client_id=' + provider.configuration.app_id + '&code=' + verification_data.code, - type: 'POST', - dataType: 'json', - success: function(result) { - provider.configuration.access_token = result.access_token; - if (typeof provider.configuration.stateCallbacks.success == "function") - provider.configuration.stateCallbacks.success(result); - }, - error: function(obj) { - var data = eval('(' + obj.responseText + ')'); - if (data.error) { - if (data.error.message == "authorization_pending") { - setTimeout(function() { - provider._processRequestToken(verification_data); - }, 2000); - } else if ("authorization_declined") { - if (typeof provider.configuration.stateCallbacks.abort == "function") - provider.configuration.stateCallbacks.abort(arguments); - } - } - } - }); - } -}, null);$data.Class.define("$data.Authentication.BasicAuth.BasicAuth", $data.Authentication.AuthenticationBase, null, { - constructor: function (cfg) { - this.configuration = $data.typeSystem.extend({ - Username: '', - Password: '' - }, cfg); - }, - Login: function (callbacks) { - if (callbacks && typeof callbacks.pending == "function") - callbacks.pending(); - }, - Logout: function () { - }, - CreateRequest: function (cfg) { - if (!cfg) - return; - var _this = this; - - var origBeforeSend = cfg.beforeSend; - cfg.beforeSend = function (xhr) { - xhr.setRequestHeader("Authorization", "Basic " + _this.__encodeBase64(_this.configuration.Username + ":" + _this.configuration.Password)); - - if(typeof origBeforeSend == "function") - origBeforeSend(xhr); - }; - - $data.ajax(cfg); - }, - __encodeBase64: function (val) { - var b64array = "ABCDEFGHIJKLMNOP" + - "QRSTUVWXYZabcdef" + - "ghijklmnopqrstuv" + - "wxyz0123456789+/" + - "="; - - input = val; - var base64 = ""; - var hex = ""; - var chr1, chr2, chr3 = ""; - var enc1, enc2, enc3, enc4 = ""; - var i = 0; - - do { - chr1 = input.charCodeAt(i++); - chr2 = input.charCodeAt(i++); - chr3 = input.charCodeAt(i++); - - enc1 = chr1 >> 2; - enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); - enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); - enc4 = chr3 & 63; - - if (isNaN(chr2)) { - enc3 = enc4 = 64; - } else if (isNaN(chr3)) { - enc4 = 64; - } - - base64 = base64 + - b64array.charAt(enc1) + - b64array.charAt(enc2) + - b64array.charAt(enc3) + - b64array.charAt(enc4); - chr1 = chr2 = chr3 = ""; - enc1 = enc2 = enc3 = enc4 = ""; - } while (i < input.length); - - return base64; - } -}, null); -$data.Class.define('$data.MetadataLoaderClass', null, null, { - load: function (metadataUri, callBack, config) { - - var cnf = { - EntityBaseClass: '$data.Entity', - ContextBaseClass: '$data.EntityContext', - AutoCreateContext: false, - DefaultNamespace: ('ns' + Math.random()).replace('.', '') + metadataUri.replace(/[^\w]/g, "_"), - ContextInstanceName: 'context', - EntitySetBaseClass: '$data.EntitySet', - CollectionBaseClass: 'Array', - url: metadataUri, - user: undefined, - password: undefined, - withCredentials: undefined, - httpHeaders: undefined, - - typeFilter: '', - navigation: true, - generateKeys: true, - dependentRelationsOnly: false - }; - - $data.typeSystem.extend( cnf, config || {}); - - if (cnf.DefaultNamespace && cnf.DefaultNamespace.lastIndexOf('.') !== (cnf.DefaultNamespace.length - 1)) - cnf.DefaultNamespace += '.'; - - this.factoryCache = this.factoryCache || {}; - callBack = $data.typeSystem.createCallbackSetting(callBack); - - if (metadataUri in this.factoryCache) { - - /*console.log("served from cache"); - console.dir(this.factoryCache[metadataUri]);*/ - callBack.success.apply({}, this.factoryCache[metadataUri]); - return; - } - - - - - var metadataUri; - if (cnf.url) { - cnf.SerivceUri = cnf.url.replace('/$metadata', ''); - if (cnf.url.indexOf('/$metadata') === -1) { - cnf.metadataUri = cnf.url.replace(/\/+$/, '') + '/$metadata'; - } else { - cnf.metadataUri = cnf.url; - } - } else { - callBack.error('metadata url is missing'); - } - - var self = this; - self._loadXMLDoc(cnf, function (xml, response) { - if (response.statusCode < 200 || response.statusCode > 299) { - callBack.error(response); - return; - } - - var versionInfo = self._findVersion(xml); - if (self.xsltRepoUrl) { - console.log('XSLT: ' + self.xsltRepoUrl + self._supportedODataVersionXSLT) - self._loadXMLDoc({ - metadataUri: self.xsltRepoUrl + self._supportedODataVersionXSLT, - user: cnf.user, - password: cnf.password, - httpHeaders: cnf.httpHeaders - }, function (xsl, response) { - if (response.statusCode < 200 || response.statusCode > 299) { - callBack.error(response); - return; - } - var text = response.responseText; - text = text.replace('xmlns:edm="@@VERSIONNS@@"', 'xmlns:edm="' + versionInfo.ns + '"'); - text = text.replace('@@VERSION@@', versionInfo.version); - - if (window.ActiveXObject === undefined) { - var parser = new DOMParser(); - xsl = parser.parseFromString(text, "text/xml"); - } else { - xsl = new ActiveXObject("Microsoft.XMLDOM"); - xsl.async = false; - xsl.loadXML(text); - } - - self._transform(callBack, versionInfo, xml, xsl, cnf); - }); - } else { - self._transform(callBack, versionInfo, xml, undefined, cnf); - } - - }); - }, - debugMode: { type: 'bool', value: false }, - xsltRepoUrl: { type: 'string', value: '' }, - - createFactoryFunc: function (ctxType, cnf, versionInfo) { - var self = this; - return function (config) { - if (ctxType) { - var cfg = $data.typeSystem.extend({ - name: 'oData', - oDataServiceHost: cnf.SerivceUri, - //maxDataServiceVersion: '', - user: cnf.user, - password: cnf.password, - withCredentials: cnf.withCredentials, - maxDataServiceVersion: versionInfo.maxVersion || '3.0' - }, config) - - - return new ctxType(cfg); - } else { - return null; - } - } - }, - - _transform: function (callBack, versionInfo, xml, xsl, cnf) { - var self = this; - var codeText = self._processResults(cnf.url, versionInfo, xml, xsl, cnf); - - try { - eval(codeText); - } catch (e) { - callBack.error(new Exception('SyntaxError', 'Unexpected model', [e, codeText])); - return; - } - - var ctxType; - if (!$data.generatedContexts || !(ctxType = $data.generatedContexts.pop())) { - callBack.error(new Exception('No context found in service', 'Not found', [cnf, codeText])); - return; - } - - var factoryFn = self.createFactoryFunc(ctxType, cnf, versionInfo); - this.factoryCache[cnf.url] = [factoryFn, ctxType]; - - factoryFn.type = ctxType; - - if (self.debugMode) { - factoryFn.codeText = codeText; - callBack.success(factoryFn, ctxType, codeText); - } - else { - callBack.success(factoryFn, ctxType); - } - }, - _loadXMLDoc: function (cnf, callback) { - var that = this; - if ($data.postMessageODataHandler) { - - if (cnf.user && cnf.password && (!cnf.httpHeaders || (cnf.httpHeaders && !cnf.httpHeaders['Authorization']))) { - httpHeader = httpHeader || {}; - httpHeader["Authorization"] = "Basic " + this.__encodeBase64(cnf.user + ":" + cnf.password); - } - - $data.postMessageODataHandler.requestProxy({ - url: cnf.metadataUri, - httpHeaders: cnf.httpHeaders, - success: function (response) { - var doc; - if (typeof module !== 'undefined' && typeof require !== 'undefined') { - doc = response.responseText; - } else if (window.ActiveXObject) { - doc = new ActiveXObject('Microsoft.XMLDOM'); - doc.async = 'false'; - doc.loadXML(response.responseText); - } else { - var parser = new DOMParser(); - doc = parser.parseFromString(response.responseText, 'text/xml'); - } - - callback(doc, response); - }, - error: function (e) { - that._loadXHTTP_XMLDoc(cnf, callback); - } - - }); - - } else { - this._loadXHTTP_XMLDoc(cnf, callback); - } - }, - _loadXHTTP_XMLDoc: function (cnf, callback) { - var xhttp = new XMLHttpRequest(); - xhttp.open("GET", cnf.metadataUri, true); - if (cnf.httpHeaders) { - Object.keys(cnf.httpHeaders).forEach(function (header) { - xhttp.setRequestHeader(header, cnf.httpHeaders[header]); - }); - } - xhttp.onreadystatechange = function () { - if (xhttp.readyState === 4) { - var response = { requestUri: cnf.metadataUri, statusCode: xhttp.status, statusText: xhttp.statusText, responseText: xhttp.responseText }; - callback(xhttp.responseXML || xhttp.responseText, response); - } - }; - - if (cnf.user && cnf.password && (!cnf.httpHeaders || (cnf.httpHeaders && !cnf.httpHeaders['Authorization']))) - xhttp.setRequestHeader("Authorization", "Basic " + this.__encodeBase64(cnf.user + ":" + cnf.password)); - - xhttp.send(""); - }, - _processResults: function (metadataUri, versionInfo, metadata, xsl, cnf) { - var transformXslt = this.getCurrentXSLTVersion(versionInfo, metadata); - cnf.typeFilter = this._prepareTypeFilter(metadata, versionInfo, cnf); - - if (window.ActiveXObject !== undefined) { - var xslt = new ActiveXObject("Msxml2.XSLTemplate.6.0"); - var xsldoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument.6.0"); - var xslproc; - xsldoc.async = false; - if (xsl) - xsldoc.load(xsl); - else - xsldoc.loadXML(transformXslt); - if (xsldoc.parseError.errorCode != 0) { - var myErr = xsldoc.parseError; - } else { - xslt.stylesheet = xsldoc; - var xmldoc = new ActiveXObject("Msxml2.DOMDocument.6.0"); - xmldoc.async = false; - xmldoc.load(metadata); - if (xmldoc.parseError.errorCode != 0) { - var myErr = xmldoc.parseError; - } else { - xslproc = xslt.createProcessor(); - xslproc.input = xmldoc; - - xslproc.addParameter('SerivceUri', cnf.SerivceUri); - xslproc.addParameter('EntityBaseClass', cnf.EntityBaseClass); - xslproc.addParameter('ContextBaseClass', cnf.ContextBaseClass); - xslproc.addParameter('AutoCreateContext', cnf.AutoCreateContext); - xslproc.addParameter('ContextInstanceName', cnf.ContextInstanceName); - xslproc.addParameter('EntitySetBaseClass', cnf.EntitySetBaseClass); - xslproc.addParameter('CollectionBaseClass', cnf.CollectionBaseClass); - xslproc.addParameter('DefaultNamespace', cnf.DefaultNamespace); - xslproc.addParameter('MaxDataserviceVersion', versionInfo.maxVersion || '3.0'); - xslproc.addParameter('AllowedTypesList', cnf.typeFilter); - xslproc.addParameter('GenerateNavigationProperties', cnf.navigation); - - xslproc.transform(); - return xslproc.output; - } - } - return ''; - } else if (typeof document !== 'undefined' && document.implementation && document.implementation.createDocument) { - var xsltStylesheet; - if (xsl) { - xsltStylesheet = xsl; - } else { - var parser = new DOMParser(); - xsltStylesheet = parser.parseFromString(transformXslt, "text/xml"); - } - - var xsltProcessor = new XSLTProcessor(); - xsltProcessor.importStylesheet(xsltStylesheet); - xsltProcessor.setParameter(null, 'SerivceUri', cnf.SerivceUri); - xsltProcessor.setParameter(null, 'EntityBaseClass', cnf.EntityBaseClass); - xsltProcessor.setParameter(null, 'ContextBaseClass', cnf.ContextBaseClass); - xsltProcessor.setParameter(null, 'AutoCreateContext', cnf.AutoCreateContext); - xsltProcessor.setParameter(null, 'ContextInstanceName', cnf.ContextInstanceName); - xsltProcessor.setParameter(null, 'EntitySetBaseClass', cnf.EntitySetBaseClass); - xsltProcessor.setParameter(null, 'CollectionBaseClass', cnf.CollectionBaseClass); - xsltProcessor.setParameter(null, 'DefaultNamespace', cnf.DefaultNamespace); - xsltProcessor.setParameter(null, 'MaxDataserviceVersion', versionInfo.maxVersion || '3.0'); - xsltProcessor.setParameter(null, 'AllowedTypesList', cnf.typeFilter); - xsltProcessor.setParameter(null, 'GenerateNavigationProperties', cnf.navigation); - resultDocument = xsltProcessor.transformToFragment(metadata, document); - - return resultDocument.textContent; - } else if (typeof module !== 'undefined' && typeof require !== 'undefined') { - var xslt = require('node_xslt'); - - return xslt.transform(xslt.readXsltString(transformXslt), xslt.readXmlString(metadata), [ - 'SerivceUri', "'" + cnf.SerivceUri + "'", - 'EntityBaseClass', "'" + cnf.EntityBaseClass + "'", - 'ContextBaseClass', "'" + cnf.ContextBaseClass + "'", - 'AutoCreateContext', "'" + cnf.AutoCreateContext + "'", - 'ContextInstanceName', "'" + cnf.ContextInstanceName + "'", - 'EntitySetBaseClass', "'" + cnf.EntitySetBaseClass + "'", - 'CollectionBaseClass', "'" + cnf.CollectionBaseClass + "'", - 'DefaultNamespace', "'" + cnf.DefaultNamespace + "'", - 'MaxDataserviceVersion', "'" + (versionInfo.maxVersion || '3.0') + "'", - 'AllowedTypesList', "'" + cnf.typeFilter + "'", - 'GenerateNavigationProperties', "'" + cnf.navigation + "'" - ]); - } - }, - _prepareTypeFilter: function (doc, versionInfo, cnf) { - var result = ''; - if (!(typeof doc === 'object' && "querySelector" in doc && "querySelectorAll" in doc)) - return result; - - var config = []; - if (typeof cnf.typeFilter === 'object' && cnf.typeFilter) { - var types = Object.keys(cnf.typeFilter); - for (var i = 0; i < types.length; i++) { - var cfg = cnf.typeFilter[types[i]]; - var typeData = {}; - if (typeof cfg === 'object' && cfg) { - if (Array.isArray(cfg)) { - typeData.Name = types[i]; - typeData.Fields = cfg; - } else { - typeData.Name = cfg.name || types[i]; - typeData.Fields = cfg.members || []; - } - } else if (cfg) { - typeData.Name = types[i]; - typeData.Fields = []; - } else { - continue; - } - - var typeShortName = typeData.Name; - var containerName = ""; - if (typeData.Name.lastIndexOf('.') > 0) - { - containerName = typeData.Name.substring(0, typeData.Name.lastIndexOf('.')); - typeShortName = typeData.Name.substring(typeData.Name.lastIndexOf('.') + 1); - } - - var conainers = doc.querySelectorAll("EntityContainer[Name = '" + containerName + "']"); - for (var j = 0; j < conainers.length; j++) { - var entitySetDef = conainers[j].querySelector("EntitySet[Name = '" + typeShortName + "']"); - if (entitySetDef != null) - { - typeData.Name = entitySetDef.attributes["EntityType"].value; - break; - } - - } - - config.push(typeData); - } - - var discoveredData; - if (cnf.dependentRelationsOnly) { - discoveredData = this._discoverProperyDependencies(config, doc, cnf.navigation, cnf.generateKeys); - } else { - discoveredData = this._discoverTypeDependencies(config, doc, cnf.navigation, cnf.generateKeys); - } - - var complex = doc.querySelectorAll("ComplexType"); - for (var i = 0; i < complex.length; i++) - { - var cns = complex[i].parentNode.attributes["Namespace"].value; - var data = !cns ? complex[i].attributes["Name"].value : (cns + "." + complex[i].attributes["Name"].value); - discoveredData.push({ Name: data, Fields: [] }); - } - - for (var i = 0; i < discoveredData.length; i++) - { - var row = discoveredData[i]; - if (row.Fields.length > 0) { - result += row.Name + ":" + row.Fields.join(",") + ";"; - } - else { - result += row.Name + ";"; - } - } - - } - - return result; - }, - _discoverTypeDependencies: function (types, doc, withNavPropertis, withKeys) { - var allowedTypes = []; - var allowedTypeNames = []; - var collect = []; - - for (var i = 0; i < types.length; i++) - { - var idx = collect.indexOf(types[i].Name); - if(idx >= 0){ - collect.splice(idx, 1); - } - this._discoverType(types[i], doc, allowedTypes, allowedTypeNames, withNavPropertis, withKeys, true, collect); - } - - for (var i = 0; i < collect.length; i++) - { - this._discoverType({ Name: collect[i], Fields: [] }, doc, allowedTypes, allowedTypeNames, withNavPropertis, withKeys, false, []); - } - - return allowedTypes; - }, - _discoverType: function(typeData, doc, allowedTypes, allowedTypeNames, withNavPropertis, withKeys, collectTypes, collectedTypes) { - var typeName = typeData.Name; - - if (allowedTypeNames.indexOf(typeName) >= 0) - { - return; - } - console.log("Discover: " + typeName); - - var typeShortName = typeName; - var typeNamespace = ''; - if (typeName.lastIndexOf('.') > 0) - { - typeNamespace = typeName.substring(0, typeName.lastIndexOf('.')); - typeShortName = typeName.substring(typeName.lastIndexOf('.') + 1); - } - - var schemaNode = doc.querySelector("Schema[Namespace = '" + typeNamespace + "']"); - if (schemaNode != null) - { - var typeNode = schemaNode.querySelector("EntityType[Name = '" + typeShortName + "'], ComplexType[Name = '" + typeShortName + "']"); - if (typeNode != null) - { - allowedTypes.push(typeData); - allowedTypeNames.push(typeName); - - if (withKeys && typeData.Fields.length > 0) { - var keys = typeNode.querySelectorAll("Key PropertyRef"); - if (keys != null) - { - for (var j = 0; j < keys.length; j++) - { - var keyField = keys[j].attributes["Name"].value; - if (typeData.Fields.indexOf(keyField) < 0) - typeData.Fields.splice(j, 0, keyField); - } - } - } - - if (withNavPropertis) - { - var navPropNodes = typeNode.querySelectorAll("NavigationProperty"); - for (var j = 0; j < navPropNodes.length; j++) - { - var navProp = navPropNodes[j]; - if (typeData.Fields.length == 0 || typeData.Fields.indexOf(navProp.attributes["Name"].value) >=0) - { - - var FromRole = navProp.attributes["FromRole"].value; - var ToRole = navProp.attributes["ToRole"].value; - - var association = schemaNode.querySelector("Association End[Role = '" + FromRole + "']:not([Type = '" + typeName + "'])"); - if (association == null) - { - association = schemaNode.querySelector("Association End[Role = '" + ToRole + "']:not([Type = '" + typeName + "'])"); - } - - if (association != null) - { - var nav_type = association.attributes["Type"].value; - - if (collectTypes) - { - if (collectedTypes.indexOf(nav_type) < 0 && allowedTypeNames.indexOf(nav_type) < 0) - collectedTypes.push(nav_type); - } - else - { - this._discoverType({ Name: nav_type, Fields: [] }, doc, allowedTypes, allowedTypeNames, withNavPropertis, withKeys, false, collectedTypes); - } - } - } - } - } - } - } - }, - - _discoverProperyDependencies: function (types, doc, withNavPropertis, withKeys) { - var allowedTypes = []; - var allowedTypeNames = types.map(function(t) { return t.Name; }); - - for (var i = 0; i < types.length; i++) - { - this._discoverProperties(types[i], doc, allowedTypes, allowedTypeNames, withNavPropertis, withKeys); - } - - return allowedTypes; - }, - _discoverProperties: function(typeData, doc, allowedTypes, allowedTypeNames, withNavPropertis, withKeys) { - var typeName = typeData.Name; - console.log("Discover: " + typeName); - - var hasProperty = typeData.Fields.length != 0; - var typeShortName = typeName; - var typeNamespace = ''; - if (typeName.lastIndexOf('.') > 0) - { - typeNamespace = typeName.substring(0, typeName.lastIndexOf('.')); - typeShortName = typeName.substring(typeName.lastIndexOf('.') + 1); - } - - var schemaNode = doc.querySelector("Schema[Namespace = '" + typeNamespace + "']"); - if (schemaNode != null) - { - var typeNode = schemaNode.querySelector("EntityType[Name = '" + typeShortName + "'], ComplexType[Name = '" + typeShortName + "']"); - if (typeNode != null) - { - allowedTypes.push(typeData); - - if (!hasProperty) - { - var properties = typeNode.querySelectorAll("Property"); - if (properties != null) - { - for (var j = 0; j < properties.length; j++) - { - var field = properties[j].attributes["Name"].value; - typeData.Fields.push(field); - } - } - - if (withNavPropertis) - { - var navPropNodes = typeNode.querySelectorAll("NavigationProperty"); - for (var j = 0; j < navPropNodes.length; j++) - { - var navProp = navPropNodes[j]; - var nav_name = navProp.attributes["Name"].value; - var types = [ navProp.attributes["FromRole"].value, navProp.attributes["ToRole"].value ]; - - var nav_type = ''; - for (var t = 0; t < types.length; t++) - { - var association = schemaNode.querySelector("Association End[Role = '" + types[t] + "']"); - if (association != null) - { - nav_type = association.attributes["Type"].value; - if (nav_type != typeName || t == 1) - break; - } - } - - if (allowedTypeNames.indexOf(nav_type) >= 0) - { - typeData.Fields.push(nav_name); - } - } - } - } - else if (withKeys) - { - var keys = typeNode.querySelectorAll("Key PropertyRef"); - if (keys != null) - { - for (var j = 0; j < keys.length; j++) - { - var keyField = keys[j].attributes["Name"].value; - if (typeData.Fields.indexOf(keyField) < 0) - typeData.Fields.splice(j, 0, keyField); - } - } - } - } - } - }, - - _findVersion: function (metadata) { - var maxDSVersion = ''; - - if (typeof metadata === 'object' && "getElementsByTagName" in metadata){ - var version = 'http://schemas.microsoft.com/ado/2008/09/edm'; - var item = metadata.getElementsByTagName('Schema'); - if (item) - item = item[0]; - if (item) - item = item.attributes; - if (item) - item = item.getNamedItem('xmlns'); - if (item) - version = item.value; - - var maxDSVersion = metadata.getElementsByTagName('edmx:DataServices')[0] || metadata.getElementsByTagName('DataServices')[0]; - if (maxDSVersion) - maxDSVersion = maxDSVersion.attributes.getNamedItem('m:MaxDataServiceVersion'); - if (maxDSVersion && version) - maxDSVersion = maxDSVersion.value; - - - var versionNum = this._supportedODataVersions[version]; - return { - ns: version, - version: versionNum || 'unknown', - maxVersion: maxDSVersion || this._maxDataServiceVersions[version || 'unknown'] - }; - }else if (typeof module !== 'undefined' && typeof require !== 'undefined'){ - var schemaXml = metadata; - - var schemaNamespace = 'http://schemas.microsoft.com/ado/2008/09/edm'; - var version = 'nodejs'; - for (var i in this._supportedODataVersions){ - if (schemaXml.search(new RegExp('= 0){ - schemaNamespace = i; - version = this._supportedODataVersions[i]; - break; - } - } - - return { - ns: schemaNamespace, - version: version, - maxVersion: this._maxDataServiceVersions[version || 'unknown'] - } - } - }, - _supportedODataVersions: { - value: { - "http://schemas.microsoft.com/ado/2006/04/edm": "V1", - "http://schemas.microsoft.com/ado/2008/09/edm": "V2", - "http://schemas.microsoft.com/ado/2009/11/edm": "V3", - "http://schemas.microsoft.com/ado/2007/05/edm": "V11", - "http://schemas.microsoft.com/ado/2009/08/edm": "V22" - } - }, - _maxDataServiceVersions: { - value: { - "http://schemas.microsoft.com/ado/2006/04/edm": "2.0", - "http://schemas.microsoft.com/ado/2008/09/edm": "2.0", - "http://schemas.microsoft.com/ado/2009/11/edm": "3.0", - "http://schemas.microsoft.com/ado/2007/05/edm": "2.0", - "http://schemas.microsoft.com/ado/2009/08/edm": "2.0" - } - }, - _supportedODataVersionXSLT: { - value: "JayDataContextGenerator.xslt" - }, - getCurrentXSLTVersion: function (versionInfo, metadata) { - return this._metadataConverterXSLT.replace('@@VERSIONNS@@', versionInfo.ns).replace('@@VERSION@@', versionInfo.version); - }, - __encodeBase64: function (val) { - var b64array = "ABCDEFGHIJKLMNOP" + - "QRSTUVWXYZabcdef" + - "ghijklmnopqrstuv" + - "wxyz0123456789+/" + - "="; - - var input = val; - var base64 = ""; - var hex = ""; - var chr1, chr2, chr3 = ""; - var enc1, enc2, enc3, enc4 = ""; - var i = 0; - - do { - chr1 = input.charCodeAt(i++); - chr2 = input.charCodeAt(i++); - chr3 = input.charCodeAt(i++); - - enc1 = chr1 >> 2; - enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); - enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); - enc4 = chr3 & 63; - - if (isNaN(chr2)) { - enc3 = enc4 = 64; - } else if (isNaN(chr3)) { - enc4 = 64; - } - - base64 = base64 + - b64array.charAt(enc1) + - b64array.charAt(enc2) + - b64array.charAt(enc3) + - b64array.charAt(enc4); - chr1 = chr2 = chr3 = ""; - enc1 = enc2 = enc3 = enc4 = ""; - } while (i < input.length); - - return base64; - }, - _metadataConverterXSLT: { - type: 'string', - value: - "\r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " Microsoft.Crm.Sdk.Data.Services.Product;Microsoft.Crm.Sdk.Data.Services.LeadAddress:Telephone1,City,UTCOffset;\r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " 0\">\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " 0\">\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " 0\">\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " 0\">\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " 0)\"/>\r\n" + - " 0)\"/>\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - "/*//////////////////////////////////////////////////////////////////////////////////////\r\n" + - "////// Autogenerated by JaySvcUtil.exe http://JayData.org for more info /////////\r\n" + - "////// oData @@VERSION@@ /////////\r\n" + - "//////////////////////////////////////////////////////////////////////////////////////*/\r\n" + - "(function(global, $data, undefined) {\r\n" + - "\r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " 0)\"/>\r\n" + - " \r\n" + - " \r\n" + - " 0)\"/>\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " 0)\"/>\r\n" + - " \r\n" + - " \r\n" + - " 0)\"/>\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " Info: generating type \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " 0)\"/>\r\n" + - " \r\n" + - " \r\n" + - " 0)\"/>\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " .extend('.', {\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " , \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " , \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " ,\r\n" + - " \r\n" + - " ,\r\n" + - " \r\n" + - " \r\n" + - " });\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - " .extend('', {\r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " ,\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " ,\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " });\r\n" + - "\r\n" + - " $data.generatedContexts = $data.generatedContexts || [];\r\n" + - " $data.generatedContexts.push();\r\n" + - " \r\n" + - " /*Context Instance*/\r\n" + - " = new ({ name:'oData', oDataServiceHost: '', maxDataServiceVersion: '' });\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - " \r\n" + - "})(window, $data);\r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " '\r\n" + - " \r\n" + - " ': { type: \r\n" + - " \r\n" + - " \r\n" + - " $data.ServiceAction\r\n" + - " \r\n" + - " \r\n" + - " $data.ServiceOperation\r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " , params: [\r\n" + - " 1) or (($IsBindable = 'false' or $IsBindable = '') and position() > 0)]\">\r\n" + - " { name: '\r\n" + - " \r\n" + - " ', type: '\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " ' }\r\n" + - " , \r\n" + - " \r\n" + - " ]\r\n" + - "\r\n" + - " }\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " , returnType: \r\n" + - " \r\n" + - " null\r\n" + - " $data.Queryable\r\n" + - " \r\n" + - " '\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " '\r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " , elementType: '\r\n" + - " \r\n" + - " '\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " , method: '\r\n" + - " \r\n" + - " '\r\n" + - " \r\n" + - " \r\n" + - " , \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " : \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " , '\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " ': '\r\n" + - " \r\n" + - " '\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " '': { type: , elementType: }\r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " , actions: { \r\n" + - " \r\n" + - " \r\n" + - " ,\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " }\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " true\r\n" + - " \r\n" + - " '': { '$':\r\n" + - " , \r\n" + - " \r\n" + - " '$':\r\n" + - " , \r\n" + - " \r\n" + - " }\r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " 'Array'\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " ''\r\n" + - " \r\n" + - " \r\n" + - " ''\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " ''\r\n" + - " \r\n" + - " \r\n" + - " ''\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " $data.ConcurrencyMode.\r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " true\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " true \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " Number.POSITIVE_INFINITY\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " true''\r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " ''\r\n" + - " ''\r\n" + - " \r\n" + - " '$$unbound'\r\n" + - " \r\n" + - " ''\r\n" + - " \r\n" + - " \r\n" + - " ''\r\n" + - " \r\n" + - " \r\n" + - " ''\r\n" + - " \r\n" + - " \r\n" + - " '$$unbound'\r\n" + - " Warning: inverseProperty other side missing: \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " ''\r\n" + - " true\r\n" + - " \r\n" + - " \r\n" + - " ''\r\n" + - " \r\n" + - " \r\n" + - " '$$unbound'\r\n" + - " \r\n" + - " Warning: inverseProperty other side missing: \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - "\r\n" + - "\r\n" + - " \r\n" + - "\r\n" + - " \r\n" + - " \r\n" + - " Warning: .: is an unknown/unprocessed attribued\r\n" + - " \r\n" + - " \r\n" + - "\r\n" - } - -}); - -$data.MetadataLoader = new $data.MetadataLoaderClass(); -$data.service = function (serviceUri, config, cb) { - var _url, _config, _callback; - function getParam(paramValue) { - switch (typeof paramValue) { - case 'object': - if (typeof paramValue.success === 'function' || typeof paramValue.error === 'function') { - _callback = paramValue; - } else { - _config = paramValue; - } - break; - case 'function': - _callback = paramValue; - break; - default: - break; - } - } - getParam(config); - getParam(cb); - - if (typeof serviceUri === 'object') { - _config = $data.typeSystem.extend(serviceUri, _config); - serviceUri = serviceUri.url; - delete _config.url; - } - - var pHandler = new $data.PromiseHandler(); - _callback = pHandler.createCallback(_callback); - - $data.MetadataLoader.load(serviceUri, { - success: function (factory) { - var type = factory.type; - //register to local store - if (_config) { - var storeAlias = _config.serviceName || _config.storeAlias; - if (storeAlias && 'addStore' in $data) { - $data.addStore(storeAlias, factory, _config.isDefault === undefined || _config.isDefault) - } - } - - _callback.success(factory, type); - }, - error: _callback.error - }, _config); - - return pHandler.getPromise(); -}; -(function ($data) { - if (typeof jQuery !== 'undefined') { - $data.Class.define('$data.Deferred', $data.PromiseHandlerBase, null, { - constructor: function () { - this.deferred = new $.Deferred(); - }, - deferred: {}, - createCallback: function (callBack) { - callBack = $data.typeSystem.createCallbackSetting(callBack); - var self = this; - - return cbWrapper = { - success: function () { - callBack.success.apply(self.deferred, arguments); - self.deferred.resolve.apply(self.deferred, arguments); - }, - error: function () { - Array.prototype.push.call(arguments, self.deferred); - callBack.error.apply(self.deferred, arguments); - }, - notify: function () { - callBack.notify.apply(self.deferred, arguments); - self.deferred.notify.apply(self.deferred, arguments); - } - }; - }, - getPromise: function () { - return this.deferred.promise(); - } - }, null); - - $data.PromiseHandler = $data.Deferred; - } -})($data); -(function ($data) { - - $data.initService = function (apiKey, options) { - var d = new $data.PromiseHandler(); - var cfg; - - if (typeof apiKey === 'object') { - //appId, serviceName, ownerid, isSSL, port, license, url - cfg = apiKey; - var protocol = cfg.isSSL || cfg.isSSL === undefined ? 'https' : 'http'; - var port = cfg.port ? (':' + cfg.port) : ''; - - if (typeof cfg.license === 'string' && cfg.license.toLowerCase() === 'business') { - if (cfg.appId && cfg.serviceName) { - apiKey = protocol + '://' + cfg.appId + '.jaystack.net' + port + '/' + cfg.serviceName; - } else { - apiKey = cfg.url; - } - } else { - if (cfg.ownerId && cfg.appId && cfg.serviceName) { - apiKey = protocol + '://open.jaystack.net/' + cfg.ownerId + '/' + cfg.appId + '/api/' + cfg.serviceName; - } else { - apiKey = cfg.url; - } - } - - delete cfg.url; - cfg = $data.typeSystem.extend(cfg, options); - } else { - cfg = options; - } - - $data.service(apiKey, cfg).then(function (factory) { - var ctx = factory(); - return ctx.onReady() - .then(function (context) { - context.serviceFactory = factory; - d.deferred.resolve(context, factory, factory.type); - }).fail(function () { - d.deferred.reject.apply(d.deferred, arguments); - }); - }).fail(function(){ - d.deferred.reject.apply(d.deferred, arguments); - }); - - return d.getPromise(); - }; - -})($data); diff --git a/release/jaydata.min.js b/release/jaydata.min.js deleted file mode 100644 index 360ec873..00000000 --- a/release/jaydata.min.js +++ /dev/null @@ -1,632 +0,0 @@ -// JayData 1.3.6 -// Dual licensed under MIT and GPL v2 -// Copyright JayStack Technologies (http://jaydata.org/licensing) -// -// JayData is a standards-based, cross-platform Javascript library and a set of -// practices to access and manipulate data from various online and offline sources. -// -// Credits: -// Hajnalka Battancs, Dániel József, János Roden, László Horváth, Péter Nochta -// Péter Zentai, Róbert Bónay, Szabolcs Czinege, Viktor Borza, Viktor Lázár, -// Zoltán Gyebrovszki, Gábor Dolla -// -// More info: http://jaydata.org -(function(a){if("object"==typeof exports&&"object"==typeof module)return a(exports);if("function"==typeof define&&define.amd)return define(["exports"],a);a(self.acorn||(self.acorn={}))})(function(a){function b(a){u=a||{};for(var b in Ua)u.hasOwnProperty(b)||(u[b]=Ua[b]);xa=u.sourceFile||null}function c(a,b){var c=sb(m,a),b=b+(" ("+c.line+":"+c.column+")"),d=new SyntaxError(b);d.pos=a;d.loc=c;d.raisedAt=k;throw d;}function d(a){function b(a){if(1==a.length)return c+="return str === "+JSON.stringify(a[0])+ -";";c+="switch(str){";for(var d=0;da?36===a: -91>a?!0:97>a?95===a:123>a?!0:170<=a&&Va.test(String.fromCharCode(a))}function f(a){return 48>a?36===a:58>a?!0:65>a?!1:91>a?!0:97>a?95===a:123>a?!0:170<=a&&tb.test(String.fromCharCode(a))}function g(){this.line=Q;this.column=k-K}function h(){Q=1;k=K=0;na=!0;j()}function i(a,b){ba=k;u.locations&&(oa=new g);s=a;j();R=b;na=a.beforeExpr}function j(){for(;k -a&&8a&&8=a?a=E(!0):(++k,a=i(ya)),a;case 40:return++k,i(N);case 41:return++k,i(L);case 59:return++k,i(O);case 44:return++k,i(S);case 91:return++k,i(pa);case 93:return++k,i(qa);case 123:return++k,i(da);case 125:return++k,i(Z);case 58:return++k,i(ea);case 63:return++k,i(za);case 48:if(a= -m.charCodeAt(k+1),120===a||88===a)return k+=2,a=z(16),null==a&&c(G+2,"Expected hexadecimal number"),e(m.charCodeAt(k))&&c(k,"Identifier directly after number"),i(fa,a);case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return E(!1);case 34:case 39:var b;a:{k++;for(var d="";;){k>=Y&&c(G,"Unterminated string constant");var f=m.charCodeAt(k);if(f===a){++k;b=i(ia,d);break a}if(92===f){var f=m.charCodeAt(++k),g=/^[0-7]+/.exec(m.slice(k,k+3));for(g&&(g=g[0]);g&&255=Y)return i(sa);var b=m.charCodeAt(k);if(e(b)||92===b)return v();a=l(b); -if(!1===a){b=String.fromCharCode(b);if("\\"===b||Va.test(b))return v();c(k,"Unexpected character '"+b+"'")}return a}function q(a,b){var c=m.slice(k,k+b);k+=b;i(a,c)}function n(){for(var a="",b,d,e=k;;){k>=Y&&c(e,"Unterminated regular expression");a=m.charAt(k);Ca.test(a)&&c(e,"Unterminated regular expression");if(b)b=!1;else{if("["===a)d=!0;else if("]"===a&&d)d=!1;else if("/"===a&&!d)break;b="\\"===a}++k}a=m.slice(e,k);++k;(b=o())&&!/^[gmsiy]*$/.test(b)&&c(e,"Invalid regexp flag");return i(Da,RegExp(a, -b))}function z(a,b){for(var c=k,d=0,e=0,f=null==b?Infinity:b;e=g?g-48:Infinity;if(g>=a)break;++k;d=d*a+g}return k===c||null!=b&&k-c!==b?null:d}function E(a){var b=k,d=!1,f=48===m.charCodeAt(k);!a&&null===z(10)&&c(b,"Invalid number");46===m.charCodeAt(k)&&(++k,z(10),d=!0);a=m.charCodeAt(k);if(69===a||101===a)a=m.charCodeAt(++k),(43===a||45===a)&&++k,null===z(10)&&c(b,"Invalid number"),d=!0;e(m.charCodeAt(k))&&c(k,"Identifier directly after number"); -var a=m.slice(b,k),g;d?g=parseFloat(a):!f||1===a.length?g=parseInt(a,10):/[89]/.test(a)||J?c(b,"Invalid number"):g=parseInt(a,8);return i(fa,g)}function A(a){a=z(16,a);null===a&&c(G,"Bad character escape sequence");return a}function o(){ha=!1;for(var a,b=!0,d=k;;){var g=m.charCodeAt(k);if(f(g))ha&&(a+=m.charAt(k)),++k;else if(92===g){ha||(a=m.slice(d,k));ha=!0;117!=m.charCodeAt(++k)&&c(k,"Expecting Unicode escape sequence \\uXXXX");++k;var g=A(4),j=String.fromCharCode(g);j||c(k-1,"Invalid Unicode escape"); -(b?e(g):f(g))||c(k-4,"Invalid Unicode escape");a+=j}else break;b=!1}return ha?a:m.slice(d,k)}function v(){var a=o(),b=aa;ha||(Gb(a)?b=Ea[a]:(u.forbidReserved&&(3===u.ecmaVersion?Hb:Ib)(a)||J&&Xa(a))&&c(G,"The keyword '"+a+"' is reserved"));return i(b,a)}function r(){Fa=G;X=ba;Ga=oa;w()}function T(a){J=a;for(k=X;kb){var e=y(a);e.left=a;e.operator=R;r();e.right=Ra(Sa(c),d,c);e=p(e,/&&|\|\|/.test(e.operator)?"LogicalExpression":"BinaryExpression");return Ra(e,b,c)}return a}function Sa(a){if(s.prefix){var b=t(),d=s.isUpdate;b.operator=R;b.prefix=!0;r();b.argument= -Sa(a);d?ta(b.argument):J&&"delete"===b.operator&&"Identifier"===b.argument.type&&c(b.start,"Deleting local variable in strict mode");return p(b,d?"UpdateExpression":"UnaryExpression")}for(a=ma(wa());s.postfix&&!U();)b=y(a),b.operator=R,b.prefix=!1,b.argument=a,ta(a),r(),a=p(b,"UpdateExpression");return a}function ma(a,b){if(x(ya)){var c=y(a);c.object=a;c.property=W(!0);c.computed=!1;return ma(p(c,"MemberExpression"),b)}return x(pa)?(c=y(a),c.object=a,c.property=I(),c.computed=!0,C(qa),ma(p(c,"MemberExpression"), -b)):!b&&x(N)?(c=y(a),c.callee=a,c.arguments=Ta(L,!1),ma(p(c,"CallExpression"),b)):a}function wa(){switch(s){case mb:var a=t();r();return p(a,"ThisExpression");case aa:return W();case fa:case ia:case Da:return a=t(),a.value=R,a.raw=m.slice(G,ba),r(),p(a,"Literal");case nb:case ob:case pb:return a=t(),a.value=s.atomValue,a.raw=s.keyword,r(),p(a,"Literal");case N:var a=ra,b=G;r();var d=I();d.start=b;d.end=ba;u.locations&&(d.loc.start=a,d.loc.end=oa);u.ranges&&(d.range=[b,ba]);C(L);return d;case pa:return a= -t(),r(),a.elements=Ta(qa,!0,!0),p(a,"ArrayExpression");case da:a=t();b=!0;d=!1;a.properties=[];for(r();!x(Z);){if(b)b=!1;else if(C(S),u.allowTrailingCommas&&x(Z))break;var e={key:s===fa||s===ia?wa():W(!0)},f=!1,g;x(ea)?(e.value=I(!0),g=e.kind="init"):5<=u.ecmaVersion&&"Identifier"===e.key.type&&("get"===e.key.name||"set"===e.key.name)?(f=d=!0,g=e.kind=e.key.name,e.key=s===fa||s===ia?wa():W(!0),s!==N&&V(),e.value=Na(t(),!1)):V();if("Identifier"===e.key.type&&(J||d))for(var j=0;jd?a.id:a.params[d],(Xa(e.name)||ua(e.name))&&c(e.start,"Defining '"+e.name+"' in strict mode"),0<=d)for(var f=0;f1&&Guard.raise(Error("Object.create implementation only accepts the first parameter."));b.prototype=a;return new b};if(!Object.keys){var a=Object.prototype.hasOwnProperty,b=!{toString:null}.propertyIsEnumerable("toString"),c=["toString","toLocaleString","valueOf","hasOwnProperty", -"isPrototypeOf","propertyIsEnumerable","constructor"],d=c.length;Object.keys=function(e){(typeof e!=="object"&&typeof e!=="function"||e===null)&&Guard.raise(new TypeError("Object.keys called on non-object"));var f=[],g;for(g in e)a.call(e,g)&&f.push(g);if(b)for(g=0;g=b.length)try{typeof document!="undefined"&&document.createTextNode("").splitText(1);return new RangeError("INDEX_SIZE_ERR")}catch(d){return d}return c[a]},set:function(d){if(isNaN(+a)||(a|0)<0||(a|0)>=b.length)try{typeof document!="undefined"&&document.createTextNode("").splitText(1);return new RangeError("INDEX_SIZE_ERR")}catch(e){return e}c[a| -0]=(d|0)&255}})},d=0;d-1:a in c};this.unregisterType=function(){Guard.raise("Unimplemented")};this.getDefault=function(b){switch(this.resolveType(b)){case a.Number:return 0;case a.Float:return 0;case a.Decimal:return"0.0";case a.Integer:return 0;case a.Int16:return 0;case a.Int32:return 0;case a.Int64:return"0"; -case a.Byte:return 0;case a.SByte:return 0;case a.String:return null;case a.Boolean:return false;default:return null}};this.getIndex=function(a){a=this.resolveType(a);return e.indexOf(a)};this.resolveByIndex=function(a){return e[a]};this.registerType=function(a,f,n){if(a){typeof f==="string"&&(f=g.resolveType(f));var o=[];if(typeof a==="string"){o=[];o.push(a)}else o=a;for(var B=0;B0){D.forEach(function(a){a(f)});i[y.fullName]=[]}}b&&b.registerType.apply(b,arguments);if(!f.name)f.name=o[0].shortName}};var o={from:{},to:{}};this.converters=o;this.convertTo=function(b,c,d,e){Guard.requireValue("typeOrName", -c);if(Object.isNullOrUndefined(b))return b;var f=Container.getTypeName(b),g=Container.resolveType(f),f=Container.resolveName(g),j=Container.resolveType(c),h=Container.resolveName(j),i;try{if(typeof j["from"+f]==="function")i=j["from"+f].apply(j,arguments);else if(typeof g["to"+h]==="function")i=g["to"+h].apply(g,arguments);else if(o.to[h]&&o.to[h][f])i=o.to[h][f].apply(o,arguments);else if(o.from[f]&&o.from[f][h])i=o.from[f][h].apply(o,arguments);else if(h===f||b instanceof j)i=b;else if(o.to[h]&& -o.to[h]["default"])i=o.to[h]["default"].apply(o,arguments);else throw"converter not found";}catch(l){Guard.raise(new Exception("Value '"+f+"' not convertable to '"+h+"'","TypeError",b))}if(j===a.Array&&d&&Array.isArray(i))for(f=0;f0&&!c[0].type)c[0].type=a.Base;for(var g=0,h=c.length;g=0},writable:false,enumerable:false,configurable:false})}if(e){this.buildStaticMembers(a,e);if(e.constructor)a.classConstructor=e.constructor}c&&this.buildInstanceMembers(a,c);b=[].concat(b);b.shift();Object.keys(b).length>0&&this.buildInstanceMixins(a,b);a.__class=true;a.prototype.constructor= -a;Object.defineProperty(a.prototype,"getType",{value:function(){return a},writable:false,enumerable:false,configurable:false})},addMethod:function(a,b,c,d){a[b]=!d||typeof intellisense!=="undefined"?c:function(){return c.apply(this[d],arguments)}},addProperty:function(a,b,c,d){if(d){c.configurable=true;if(c.get){var e=c.get;c.get=function(){this[d]||Guard.raise(new Exception("not inicialized"));return e.apply(this[d],arguments)}}if(c.set){var f=c.set;c.set=function(){this[d]||Guard.raise(new Exception("not inicialized")); -f.apply(this[d],arguments)}}}Object.defineProperty(a,b,c)},addField:function(){Guard.raise("not implemented")},buildMethod:function(a,b,c){this.addMethod(b.classMember?a:a.prototype,b.name,b.method,c)},buildProperty:function(a,b,c){var d=b.classMember?a:a.prototype,e=b.createPropertyDescriptor(a);this.addProperty(d,b.name,e,c);if(!b.classMember&&a.__setPropertyfunctions==true&&b.withoutGetSetMethod!==true&&!("get_"+b.name in d||"set_"+b.name in d)){a=b.createGetMethod();this.addProperty(d,"get_"+ -b.name,a,c);a=b.createSetMethod();this.addProperty(d,"set_"+b.name,a,c)}},buildMember:function(a,b,c,e){e=e||"memberDefinitions";a[e]=a[e]||new d;a[e].setMember(b);switch(b.kind){case f.method:this.buildMethod(a,b,c);break;case f.navProperty:case f.complexProperty:case f.property:this.buildProperty(a,b,c);break;default:Guard.raise("Unknown member type: "+b.kind+","+b.name)}},buildStaticMembers:function(a,b){for(var d in b)if(b.hasOwnProperty(d)){var e=c.translateDefinition(b[d],d,a);e.classMember= -true;this.buildMember(a,e,void 0,"staticDefinitions")}},buildInstanceMembers:function(a,b){for(var d in b)if(b.hasOwnProperty(d)){var e=c.translateDefinition(b[d],d,a);this.buildMember(a,e,void 0,"memberDefinitions")}},copyMembers:function(a,b){Object.keys(a.prototype).forEach(function(c){if(c!=="constructor"&&c!=="toString"){typeof intellisense!=="undefined"&&intellisense.logMessage("copying item:"+c);b.prototype[c]=a[c]}})},buildInstanceMixins:function(a,b){a.mixins=a.mixins||[];a.propagations= -a.propagations||[];for(var c=0;c0&&arguments[arguments.length-1]&&typeof arguments[arguments.length-1].reject==="function"){(console.error||console.log).call(console,arguments[0]);arguments[arguments.length-1].reject.apply(arguments[arguments.length-1],arguments)}else arguments[0]instanceof Error?Guard.raise(arguments[0]):Guard.raise(new Exception("DEFAULT ERROR CALLBACK!","DefaultError",arguments))};$data.defaultSuccessCallback=function(){};$data.defaultNotifyCallback=function(){}; -$data.typeSystem={__namespace:!0,extend:function(a){typeof a!=="object"&&typeof a!=="function"&&Guard.raise("Target must be object or function");for(var b=1;b=0){b=a.substring(0,b).toLowerCase();if((b=$data.GeographyBase.registered[b])&&b.parseFromString&&b!=$data.GeographyBase)return b.parseFromString(a);Guard.raise(new Exception("parseFromString","Not Implemented",a))}}; -$data.GeographyBase.stringifyToUrl=function(a){if(a instanceof $data.GeographyBase&&a.constructor&&a.constructor.stringifyToUrl)return a.constructor.stringifyToUrl(a);if(a instanceof $data.GeographyBase&&a.constructor&&Array.isArray(a.constructor.validMembers)&&a.constructor.validMembers[0]==="coordinates"){var b="geography'"+a.type.toUpperCase()+"(",c=function(a){if(Array.isArray(a[0]))for(var e=0;e0&&(b=b+",");Array.isArray(a[e][0])&&(b=b+"(");c(a[e]);Array.isArray(a[e][0])&&(b= -b+")")}else b=b+a.join(" ")};c(a.coordinates,b);return b=b+")'"}Guard.raise(new Exception("stringifyToUrl on instance type","Not Implemented",a))};$data.GeographyBase.registerType=function(a,b,c){$data.SimpleBase.registerType(a,b,c||$data.GeographyBase);$data.GeographyBase.registered=$data.GeographyBase.registered||{};$data.GeographyBase.registered[a.toLowerCase()]=b}; -$data.GeographyBase.validateGeoJSON=function(a){var b=a.type;if(b){var c=$data.GeographyBase.registered[b.toLowerCase()];if(typeof c.validateGeoJSON==="function"){if(c=c.validateGeoJSON(a))return c;Guard.raise(new Exception("Invalid '"+b+"' format!","Format Exception",a))}}console.log("GeoJSON validation missing",a)};$data.SimpleBase.registerType("GeographyBase",$data.GeographyBase,$data.Geospatial);$data.Container.registerType(["$data.GeographyBase"],$data.GeographyBase); -$data.GeographyPoint=function(a,b){a&&typeof a==="object"&&Array.isArray(a)?$data.GeographyBase.call(this,{coordinates:a}):a&&typeof a==="object"&&("longitude"in a||"latitude"in a)?$data.GeographyBase.call(this,{coordinates:[a.longitude,a.latitude]}):a&&typeof a==="object"&&("lng"in a||"lat"in a)?$data.GeographyBase.call(this,{coordinates:[a.lng,a.lat]}):a&&typeof a==="object"?$data.GeographyBase.call(this,a):$data.GeographyBase.call(this,{coordinates:[a||0,b||0]})}; -$data.GeographyPoint.validateGeoJSON=function(a){return a&&Array.isArray(a.coordinates)&&a.coordinates.length==2&&typeof a.coordinates[0]==="number"&&typeof a.coordinates[1]==="number"};$data.GeographyPoint.parseFromString=function(a){a=a.substring(a.indexOf("(")+1,a.lastIndexOf(")")).split(" ");return new $data.GeographyPoint(parseFloat(a[0]),parseFloat(a[1]))};$data.GeographyPoint.validMembers=["coordinates"];$data.GeographyBase.registerType("Point",$data.GeographyPoint); -Object.defineProperty($data.GeographyPoint.prototype,"longitude",{get:function(){return this.coordinates[0]},set:function(a){this.coordinates[0]=a}});Object.defineProperty($data.GeographyPoint.prototype,"latitude",{get:function(){return this.coordinates[1]},set:function(a){this.coordinates[1]=a}});$data.Container.registerType("$data.GeographyPoint,GeographyPoint,$data.Geography,Geography,geography,geo".split(","),$data.GeographyPoint);$data.Geography=$data.GeographyPoint; -$data.GeographyLineString=function(a){Array.isArray(a)?$data.GeographyBase.call(this,{coordinates:a}):$data.GeographyBase.call(this,a)};$data.GeographyLineString.validateGeoJSON=function(a){for(var b=a&&Array.isArray(a.coordinates),c=0;b&&c=0){b=a.substring(0,b).toLowerCase();if((b=$data.GeometryBase.registered[b])&&b.parseFromString&&b!=$data.GeometryBase)return b.parseFromString(a);Guard.raise(new Exception("parseFromString","Not Implemented",a))}}; -$data.GeometryBase.stringifyToUrl=function(a){if(a instanceof $data.GeometryBase&&a.constructor&&a.constructor.stringifyToUrl)return a.constructor.stringifyToUrl(a);if(a instanceof $data.GeometryBase&&a.constructor&&Array.isArray(a.constructor.validMembers)&&a.constructor.validMembers[0]==="coordinates"){var b="geometry'"+a.type.toUpperCase()+"(",c=function(a){if(Array.isArray(a[0]))for(var e=0;e0&&(b=b+",");Array.isArray(a[e][0])&&(b=b+"(");c(a[e]);Array.isArray(a[e][0])&&(b=b+")")}else b= -b+a.join(" ")};c(a.coordinates,b);return b=b+")'"}Guard.raise(new Exception("stringifyToUrl on instance type","Not Implemented",a))};$data.GeometryBase.registerType=function(a,b,c){$data.SimpleBase.registerType(a,b,c||$data.GeometryBase);$data.GeometryBase.registered=$data.GeometryBase.registered||{};$data.GeometryBase.registered[a.toLowerCase()]=b}; -$data.GeometryBase.validateGeoJSON=function(a){var b=a.type;if(b){var c=$data.GeometryBase.registered[b.toLowerCase()];if(typeof c.validateGeoJSON==="function"){if(c=c.validateGeoJSON(a))return c;Guard.raise(new Exception("Invalid '"+b+"' format!","Format Exception",a))}}console.log("GeoJSON validation missing",a)};$data.SimpleBase.registerType("GeometryBase",$data.GeometryBase,$data.Geospatial);$data.Container.registerType(["$data.GeometryBase"],$data.GeometryBase); -$data.GeometryPoint=function(a,b){a&&typeof a==="object"&&Array.isArray(a)?$data.GeometryBase.call(this,{coordinates:a}):a&&typeof a==="object"&&("x"in a||"y"in a)?$data.GeometryBase.call(this,{coordinates:[a.x,a.y]}):a&&typeof a==="object"?$data.GeometryBase.call(this,a):$data.GeometryBase.call(this,{coordinates:[a||0,b||0]})}; -$data.GeometryPoint.validateGeoJSON=function(a){return a&&Array.isArray(a.coordinates)&&a.coordinates.length==2&&typeof a.coordinates[0]==="number"&&typeof a.coordinates[1]==="number"};$data.GeometryPoint.parseFromString=function(a){a=a.substring(a.indexOf("(")+1,a.lastIndexOf(")")).split(" ");return new $data.GeometryPoint(parseFloat(a[0]),parseFloat(a[1]))};$data.GeometryPoint.validMembers=["coordinates"];$data.GeometryBase.registerType("Point",$data.GeometryPoint); -Object.defineProperty($data.GeometryPoint.prototype,"x",{get:function(){return this.coordinates[0]},set:function(a){this.coordinates[0]=a}});Object.defineProperty($data.GeometryPoint.prototype,"y",{get:function(){return this.coordinates[1]},set:function(a){this.coordinates[1]=a}});$data.Container.registerType(["$data.GeometryPoint","GeometryPoint"],$data.GeometryPoint); -$data.GeometryLineString=function(a){Array.isArray(a)?$data.GeometryBase.call(this,{coordinates:a}):$data.GeometryBase.call(this,a)};$data.GeometryLineString.validateGeoJSON=function(a){for(var b=a&&Array.isArray(a.coordinates),c=0;b&&c>1),c=0,d=1,e=0;c=Math.pow(2,1-d)){g=Math.min(Math.floor(Math.log(a)/Math.LN2),d);f=g+d;d=Math.round(a*Math.pow(2,c-g)-Math.pow(2,c))}else{f=0;d=Math.round(a/Math.pow(2,1-d-c))}}for(a=[];c;c=c-1){a.push(d%2?1:0);d=Math.floor(d/2)}for(c=b;c;c=c-1){a.push(f%2?1:0);f=Math.floor(f/2)}a.push(e? -1:0);a.reverse();b=a.join("");for(e=[];b.length;){e.push(parseInt(b.substring(0,8),2));b=b.substring(8)}return e}; -$data.unpackIEEE754=function(a,b,c){var d=[],e,f,g;for(e=a.length;e;e=e-1){g=a[e-1];for(f=8;f;f=f-1){d.push(g%2?1:0);g=g>>1}}d.reverse();f=d.join("");a=(1<0?d*Math.pow(2,e-a)*(1+f/Math.pow(2,c)):f!==0?d*Math.pow(2,-(a-1))*(f/Math.pow(2,c)):d<0?-0.0:0};$data.IEEE754=function(a,b,c){return $data.unpackIEEE754($data.packIEEE754(a,b,c),b,c)}; -$data.Container.registerConverter("$data.Float",{"default":function(a){a=+a;if(isNaN(a))throw 0;return $data.IEEE754(a,8,23)}});$data.Container.registerConverter("$data.Int16",{"default":function(a){a=(a|0)&65535;return a>=32768?a-65536:a}}); -$data.Container.registerConverter("$data.Int64",{"$data.Boolean":function(a){return a?"1":"0"},"$data.Number":function(a){a=a.toString();if(a.indexOf(".")>0)return a.split(".")[0];if(a.indexOf(".")==0)throw 0;return a},"$data.String":function(a){if(!/^\-?([0-9]+(\.[0-9]+)?|Infinity)$/.test(a))throw 0;if(a.indexOf(".")>0)return a.split(".")[0];if(a.indexOf(".")==0)throw 0;return a},"$data.Date":function(a){a=a.valueOf();if(isNaN(a))throw 0;return a.toString()}}); -$data.Container.registerConverter("$data.SByte",{"default":function(a){a=(a|0)&255;return a>=128?a-256:a}});$data.Container.registerConverter("$data.String",{"$data.Date":function(a){return a.toISOString()},"$data.ObjectID":function(a){return btoa(a.toString())},"default":function(a){return typeof a==="object"?JSON.stringify(a):a.toString()}});$data.Container.registerConverter("$data.Object",{"$data.String":function(a){return JSON.parse(a)},"$data.Function":function(){throw 0;}}); -$data.Container.registerConverter("$data.Array",{"$data.String":function(a){a=JSON.parse(a);if(!Array.isArray(a))throw 0;return a}});$data.Container.registerConverter("$data.ObjectID",{"$data.ObjectID":function(a){try{return btoa(a.toString())}catch(b){return a}},"$data.String":function(a){return a}});$data.Container.proxyConverter=function(a){return a};$data.Container.defaultConverter=function(a){return function(b){return $data.Container.convertTo(b,a)}}; -$data.StringFunctions={startsWith:function(){var a,b;if(arguments.length==2){a=arguments[0];b=arguments[1]}else if(arguments.length==1&&typeof this==="string"){a=this;b=arguments[0]}else if(this instanceof String){a=this.valueOf();b=arguments[0]}else return false;return typeof a!=="string"?false:a.indexOf(b)===0},endsWith:function(){var a,b;if(arguments.length==2){a=arguments[0];b=arguments[1]}else if(arguments.length==1&&typeof this==="string"){a=this;b=arguments[0]}else if(this instanceof String){a= -this.valueOf();b=arguments[0]}else return false;return typeof a!=="string"?false:a.slice(-b.length)===b},contains:function(){var a,b;if(arguments.length==2){a=arguments[0];b=arguments[1]}else if(arguments.length==1&&typeof this==="string"){a=this;b=arguments[0]}else if(this instanceof String){a=this.valueOf();b=arguments[0]}else return false;return typeof a!=="string"?false:a.indexOf(b)>=0}}; -$data.Class.define("$data.Expressions.ExpressionType",null,null,{},{Constant:"constant",Variable:"variable",MemberAccess:"memberAccess",Call:"call",Equal:"equal",NotEqual:"notEqual",EqualTyped:"equalTyped",NotEqualTyped:"notEqualTyped",GreaterThen:"greaterThan",LessThen:"lessThan",GreaterThenOrEqual:"greaterThanOrEqual",LessThenOrEqual:"lessThenOrEqual",Or:"or",OrBitwise:"orBitwise",And:"and",AndBitwise:"andBitwise",In:"in",Add:"add",Divide:"divide",Multiply:"multiply",Subtract:"subtract",Modulo:"modulo", -ArrayIndex:"arrayIndex",New:"new",Positive:"positive",Negative:"negative",Increment:"increment",Decrement:"decrement",Not:"not",This:"this",LambdaParameterReference:"lambdaParameterReference",LambdaParameter:"lambdaParameter",Parameter:"parameter",ArrayLiteral:"arrayLiteral",ObjectLiteral:"objectLiteral",ObjectField:"objectField",Function:"Function",Unknown:"UNKNOWN",EntitySet:"EntitySet",ServiceOperation:"ServiceOperation",EntityField:"EntityField",EntityContext:"EntityContext",Entity:"Entity",Filter:"Filter", -First:"First",Count:"Count",InlineCount:"InlineCount",Single:"Single",Find:"Find",Some:"Some",Every:"Every",ToArray:"ToArray",BatchDelete:"BatchDelete",ForEach:"ForEach",Projection:"Projection",EntityMember:"EntityMember",EntityFieldOperation:"EntityFieldOperation",FrameOperation:"FrameOperation",EntityFunctionOperation:"EntityFunctionOperation",ContextFunctionOperation:"ContextFunctionOperation",EntityBinary:"EntityBinary",Code:"Code",ParametricQuery:"ParametricQuery",MemberInfo:"MemberInfo",QueryParameter:"QueryParameter", -ComplexEntityField:"ComplexEntityField",Take:"Take",Skip:"Skip",OrderBy:"OrderBy",OrderByDescending:"OrderByDescending",Include:"Include",IndexedPhysicalAnd:"IndexedDBPhysicalAndFilterExpression",IndexedLogicalAnd:"IndexedDBLogicalAndFilterExpression",IndexedLogicalOr:"IndexedDBLogicalOrFilterExpression",IndexedLogicalIn:"IndexedDBLogicalInFilterExpression"});$data.BinaryOperator=function(){}; -$data.binaryOperators=[{operator:"==",expressionType:$data.Expressions.ExpressionType.Equal,type:"boolean",implementation:function(a,b){return a==b}},{operator:"===",expressionType:$data.Expressions.ExpressionType.EqualTyped,type:"boolean",implementation:function(a,b){return a===b}},{operator:"!=",expressionType:$data.Expressions.ExpressionType.NotEqual,type:"boolean",implementation:function(a,b){return a!=b}},{operator:"!==",expressionType:$data.Expressions.ExpressionType.NotEqualTyped,type:"boolean", -implementation:function(a,b){return a!==b}},{operator:">",expressionType:$data.Expressions.ExpressionType.GreaterThen,type:"boolean",implementation:function(a,b){return a>b}},{operator:">=",expressionType:$data.Expressions.ExpressionType.GreaterThenOrEqual,type:"boolean",implementation:function(a,b){return a>=b}},{operator:"<=",expressionType:$data.Expressions.ExpressionType.LessThenOrEqual,type:"boolean",implementation:function(a,b){return a<=b}},{operator:"<",expressionType:$data.Expressions.ExpressionType.LessThen, -type:"boolean",implementation:function(a,b){return a0)return a};$data.binaryOperators.contains=function(a){return $data.binaryOperators.some(function(b){return b.operator==a})};$data.binaryOperators.getOperator=function(a){var b=$data.binaryOperators.filter(function(b){return b.operator==a});b.length<1&&Guard.raise("Unknown operator: "+a);return b[0]}; -$data.unaryOperators=[{operator:"+",arity:"prefix",expressionType:$data.Expressions.ExpressionType.Positive,type:"number",implementation:function(a){return+a}},{operator:"-",arity:"prefix",expressionType:$data.Expressions.ExpressionType.Negative,type:"number",implementation:function(a){return-a}},{operator:"++",arity:"prefix",expressionType:$data.Expressions.ExpressionType.Increment,type:"number",implementation:function(a){return++a}},{operator:"--",arity:"prefix",expressionType:$data.Expressions.ExpressionType.Decrement, -type:"number",implementation:function(a){return--a}},{operator:"++",arity:"suffix",expressionType:$data.Expressions.ExpressionType.Increment,type:"number",implementation:function(a){return a++}},{operator:"!",arity:"prefix",expressionType:$data.Expressions.ExpressionType.Not,type:"boolean",implementation:function(a){return!a}},{operator:"--",arity:"suffix",expressionType:$data.Expressions.ExpressionType.Decrement,type:"number",implementation:function(a){return a--}}]; -$data.unaryOperators.resolve=function(a){if($data.unaryOperators.filter(function(b){return b.operator==a}).length>0)return a};$data.unaryOperators.contains=function(a){return $data.unaryOperators.some(function(b){return b.operator==a})};$data.unaryOperators.getOperator=function(a,b){var c=$data.unaryOperators.filter(function(c){return c.operator==a&&(!b||c.arity==b)});c.length<1&&Guard.raise("Unknown operator: "+a);return c[0]}; -$data.timeIt=function(a,b){b=b||1;console.time("!");for(var c=0;c-1?$data.Expressions.ExpressionType.LambdaParameterReference:$data.Expressions.ExpressionType.Parameter)},ParserObjectExpression:function(a){for(var b=Array(a.properties.length),c=0;c":{expressionType:$data.Expressions.ExpressionType.GreaterThen,type:"boolean",implementation:function(a,b){return a>b}},">=":{expressionType:$data.Expressions.ExpressionType.GreaterThenOrEqual,type:"boolean",implementation:function(a, -b){return a>=b}},"<=":{expressionType:$data.Expressions.ExpressionType.LessThenOrEqual,type:"boolean",implementation:function(a,b){return a<=b}},"<":{expressionType:$data.Expressions.ExpressionType.LessThen,type:"boolean",implementation:function(a,b){return a=0,e=c==b.paramsName;!e&&!d&&Guard.raise("Variable is not defined in the paramContext or the lambda parameters: "+c);return $data.Expressions.ExpressionNodeTypes.MemberAccessExpressionNode.create(e,a.expression,a.member)}},null); -$data.Class.define("$data.Expressions.ExecutorVisitor",$data.Expressions.ExpTreeVisitor,null,{VisitVariable:function(a,b){if(!a.executable)return a;var c=a.name==b.paramsName?b.paramContext:window[a.name];typeof c=="undefined"&&Guard.raise(new Exception("Unknown variable in '"+b.operation+"' operation. The variable isn't referenced in the parameter context and it's not a global variable: '"+a.name+"'.","InvalidOperation",{operationName:b.operation,missingParameterName:a.name}));return $data.Expressions.ExpressionNodeTypes.LiteralExpressionNode.create(true, -typeof c,c)},VisitMember:function(a,b){if(!a.executable)return a;for(var c=this.GetMemberChain(a),d,e=0;e","<",">=","<="].indexOf(a.value)>=0?c=this.BuildEquality(a,b):["&&","||"].indexOf(a.value)>=0?c=this.BuildBinary(a,b):["+","-","*","/","%"].indexOf(a.value)>=0?c=this.BuildBinary(a,b):"["==a.value?c=this.BuildArrayAccess(a,b):Guard.raise("Value of infix node isn't implemented: "+a.value);break;case "prefix":["+","-","!"].indexOf(a.value)>=0?c=this.BuildUnary(a,b):["++","--"].indexOf(a.value)>=0?c=this.BuildIncDec(a,b):"{"==a.value?c=this.BuildNewExpression(a,b):Guard.raise("Value of prefix node isn't implemented: "+ -a.value);break;case "suffix":["++","--"].indexOf(a.value)>=0?c=this.BuildIncDec(a,b):Guard.raise("Value of suffix node isn't implemented: "+a.value);break;case "string":case "number":c=this.BuildLiteral(a,b);break;case "ternary":a.value=="?"?c=this.BuildDecision(a,b):Guard.raise("Value of ternary node isn't implemented: "+a.value);break;case null:case void 0:c=a.type=="boolean"&&(a.value=="true"||a.value=="false")?this.BuildBoolLiteral(a,b):this.BuildVariable(a,b);break;default:Guard.raise("Arity isn't implemented: "+ -a.arity)}return c},BuildNewExpression:function(a){for(var b=$data.Expressions.ExpressionNodeTypes.NewExpressionNode.create(true,[]),a=a.first,c=0;c=b.pageSize;c=Container.createConstantExpression(Math.max(c,0),"number"); -return Container.createPagingExpression(a.source,c,a.nodeType)}if(b.append)b.abort=true;break;case "next":if(a.nodeType===$data.Expressions.ExpressionType.Skip){c=b.pageSize+a.amount.value;c=Container.createConstantExpression(c,"number");return Container.createPagingExpression(a.source,c,a.nodeType)}if(b.append){c=Container.createConstantExpression(b.pageSize,"number");return Container.createPagingExpression(a,c,$data.Expressions.ExpressionType.Skip)}}this.Visit(a.source,b)}}); -$data.Class.define("$data.Validation.ValidationError",null,null,{constructor:function(a,b,c){this.Message=a;this.PropertyDefinition=b;this.Type=c},Type:{dataType:"string"},Message:{dataType:"string"},PropertyDefinition:{dataType:$data.MemberDefinition}},null); -$data.Class.define("$data.Validation.EntityValidationBase",null,null,{ValidateEntity:function(){return[]},ValidateEntityField:function(){return[]},getValidationValue:function(){Guard.raise("Pure class")},getValidationMessage:function(){Guard.raise("Pure class")}},null);$data.Validation=$data.Validation||{};$data.Validation.Entity=new $data.Validation.EntityValidationBase; -$data.Class.define("$data.Validation.Defaults",null,null,null,{validators:{value:{required:function(a){return!Object.isNullOrUndefined(a)},customValidator:function(a,b){return Object.isNullOrUndefined(a)||typeof b=="function"?b(a):true},minValue:function(a,b){return Object.isNullOrUndefined(a)||a>=b},maxValue:function(a,b){return Object.isNullOrUndefined(a)||a<=b},minLength:function(a,b){return Object.isNullOrUndefined(a)||a.length>=b},maxLength:function(a,b){return Object.isNullOrUndefined(a)||a.length<= -b},length:function(a,b){return Object.isNullOrUndefined(a)||a.length==b},regex:function(a,b){return Object.isNullOrUndefined(a)||a.match(typeof b==="string"?RegExp(b.indexOf("/")===0&&b.lastIndexOf("/")===b.length-1?b.slice(1,-1):b):b)}}},_getGroupValidations:function(a){var b={};if(Array.isArray(a))for(var c=0;c-1){var g=d.getMember(f),h=Container.resolveType(g.type), -i=a[f];if(g.concurrencyMode===$data.ConcurrencyMode.Fixed)this.initData[f]=i;else{if(b&&b.converters){var j=b.converters[Container.resolveName(h)];j&&(i=j(i))}this.initData[f]=Container.convertTo(i,h,g.elementType,b)}}}b&&b.entityBuilder&&b.entityBuilder(this,c.memberDefinitions.asArray(),c);this.entityState=this.changedProperties=void 0},toString:function(){return this.getType().fullName+"("+(this.Id||this.Name||"")+")"},toJSON:function(){var a={},b=this;this.getType().memberDefinitions.getPublicMappedProperties().forEach(function(c){a[c.name]= -b[c.name]instanceof Date&&c.type&&Container.resolveType(c.type)===$data.DateTimeOffset?new $data.DateTimeOffset(b[c.name]):b[c.name]});return a},equals:function(a){if(a.getType()!==this.getType())return false;for(var b=this.getType().memberDefinitions.getKeyProperties(),c=0;c0){d=this[a.name];d=new PropertyValidationEventData(a.name,d,b,e);this._propertyValidationError&&this.propertyValidationError.fire(d);"instancePropertyValidationError"in this.constructor&&this.constructor.instancePropertyValidationError.fire(d, -this);if(d.cancel==true)return}}a.storeOnObject==true?this["_"+a.name]=b:this.initData[a.name]=b;this.isValidated=false;if(a.monitorChanges!=false&&this.entityState==$data.EntityState.Unchanged)this.entityState=$data.EntityState.Modified;this._setPropertyChanged(a);if(a.monitorChanges!=false){this._propertyChanged&&this.propertyChanged.fire(c);"instancePropertyChanged"in this.constructor&&this.constructor.instancePropertyChanged.fire(c,this)}},_setPropertyChanged:function(a){if(a.monitorChanges!= -false){if(!this.changedProperties)this.changedProperties=[];this.changedProperties.some(function(b){return b.name==a.name})||this.changedProperties.push(a)}},retrieveProperty:function(a){return a.storeOnObject==true?this["_"+a.name]:this.initData[a.name]},getProperty:function(a,b,c){b=$data.typeSystem.createCallbackSetting(b);if(this[a.name]!=void 0)c instanceof $data.Transaction?b.success(this[a.name],c):b.success(this[a.name]);else{var d=this.context;if(this.context)return d.loadItemProperty(this, -a,b,c);try{var e=this,f=this.storeToken||this.getType().storeToken;if(f&&typeof f.factory==="function")return f.factory().onReady().then(function(c){return c.loadItemProperty(e,a,b)})}catch(g){}Guard.raise(new Exception("Entity not in context","Invalid operation"))}},setProperty:function(a,b,c){this[a.name]=b;b=new $data.PromiseHandler;c=b.createCallback(c);c.success(this[a.name]);return b.getPromise()},isValid:function(){if(!this.isValidated){this.ValidationErrors=$data.Validation.Entity.ValidateEntity(this); -this.isValidated=true}return this.ValidationErrors.length==0},isValidated:{dataType:"bool",storeOnObject:!0,monitorChanges:!1,notMapped:!0,enumerable:!1,value:!1},ValidationErrors:{dataType:Array,elementType:$data.Validation.ValidationError,storeOnObject:!0,monitorChanges:!0,notMapped:!0,enumerable:!1},resetChanges:function(){delete this._changedProperties},changedProperties:{dataType:Array,elementType:window.MemberDefinition,storeOnObject:!0,monitorChanges:!1,notMapped:!0,enumerable:!1},entityState:{dataType:"integer", -storeOnObject:!0,monitorChanges:!1,notMapped:!0,enumerable:!1},remove:function(){if($data.ItemStore&&"EntityInstanceRemove"in $data.ItemStore)return $data.ItemStore.EntityInstanceRemove.apply(this,arguments);throw"not implemented";},save:function(){if($data.ItemStore&&"EntityInstanceSave"in $data.ItemStore)return $data.ItemStore.EntityInstanceSave.apply(this,arguments);throw"not implemented";},refresh:function(){if($data.ItemStore&&"EntityInstanceSave"in $data.ItemStore)return $data.ItemStore.EntityInstanceRefresh.apply(this, -arguments);throw"not implemented";},storeToken:{type:Object,monitorChanges:!1,notMapped:!0,storeOnObject:!0},getFieldUrl:function(a){if(this.context)return this.context.getFieldUrl(this,a);if(this.getType().storeToken&&typeof this.getType().storeToken.factory==="function")return this.getType().storeToken.factory().getFieldUrl(this,a);if(this.getType().storeToken)try{var b=$data.ItemStore._getContextPromise("default",this.getType());if(b instanceof $data.EntityContext)return b.getFieldUrl(this,a)}catch(c){}return"#"}}, -{__setPropertyfunctions:{value:!0,notMapped:!0,enumerable:!1,storeOnObject:!0},__copyPropertiesToInstance:{value:!1,notMapped:!0,enumerable:!1,storeOnObject:!0},inheritedTypeProcessor:function(a){$data.ItemStore&&"EntityInheritedTypeProcessor"in $data.ItemStore&&$data.ItemStore.EntityInheritedTypeProcessor.apply(this,arguments);a.defaultValues={};a.memberDefinitions.asArray().forEach(function(b){if(b.hasOwnProperty("defaultValue"))a.defaultValues[b.name]=b.defaultValue});if(Object.keys(a.defaultValues).length> -0)a.setDefaultValues=function(b,c){var b=b||{},d=a.defaultValues,e;for(e in d)e in b||(b[e]="function"===typeof d[e]?d[e](e,c):d[e]);return b}},addEventListener:function(a,b){var c="on"+a;c in this||(this[c]=new $data.Event(a,this));this[c].attach(b)},removeEventListener:function(a,b){var c="on"+a;c in this&&this[c].detach(b)},raiseEvent:function(a,b){var c="on"+a;c in this&&this[c].fire(b)},getFieldNames:function(){return this.memberDefinitions.getPublicMappedPropertyNames()},"from$data.Object":function(a, -b,c,d){if(Object.isNullOrUndefined(a))return a;var e;d&&d.converters&&(e={converters:d.converters});return new this(a,e)}}); -$data.define=function(a,b,c){if(b&&!(b instanceof $data.ContainerClass)){c=b;b=void 0}if(!c)throw Error("json object type is not supported yet");var d={},e=[];Object.keys(c).forEach(function(a){var b=c[a];if(typeof b==="object"&&("type"in b||"get"in b||"set"in b)){d[a]=b;b.key&&e.push(b);if(("get"in b||"set"in b)&&(!("notMapped"in b)||b.notMapped===true)){b.notMapped=true;b.storeOnObject=true}if("get"in b&&!("set"in b))b.set=function(){};else if("set"in b&&!("get"in b))b.get=function(){}}else d[a]= -{type:b}});if(e.length<1){var f;switch(true){case "id"in d:f="id";break;case "Id"in d:f="Id";break;case "ID"in d:f="ID"}if(f){d[f].key=true;$data.Container.resolveName(d[f].type);d[f].computed=true}else d.Id={type:"int",key:true,computed:true}}return $data.Entity.extend(a,b,d)};$data.implementation=function(a){return Container.resolveType(a)};(function(){$data.defaults=$data.defaults||{};$data.defaults.defaultDatabaseName="JayDataDefault"})(); -$data.Class.define("$data.StorageModel",null,null,{constructor:function(){this.ComplexTypes=[];this.Associations=[]},LogicalType:{},LogicalTypeName:{},PhysicalType:{},PhysicalTypeName:{},EventHandlers:{},TableName:{},TableOptions:{value:void 0},ComplexTypes:{},Associations:{},ContextType:{},Roles:{}},null); -$data.Class.define("$data.Association",null,null,{constructor:function(a){if(a){this.From=a.From;this.FromType=a.FromType;this.FromMultiplicity=a.FromMultiplicity;this.FromPropertyName=a.FromPropertyName;this.To=a.To;this.ToType=a.ToType;this.ToMultiplicity=a.ToMultiplicity;this.ToPropertyName=a.ToPropertyName}},From:{},FromType:{},FromMultiplicity:{},FromPropertyName:{},To:{},ToType:{},ToMultiplicity:{},ToPropertyName:{},ReferentialConstraint:{}},null); -$data.Class.define("$data.ComplexType",$data.Association,null,{},null); -$data.Class.define("$data.EntityContext",null,null,{constructor:function(a){$data.ItemStore&&"ContextRegister"in $data.ItemStore&&$data.ItemStore.ContextRegister.apply(this,arguments);if(a.queryCache)this.queryCache=a.queryCache;"string"===typeof a&&(a=0===a.indexOf("http")?{name:"oData",oDataServiceHost:a}:{name:"local",databaseName:a});if("provider"in a)a.name=a.provider;this.trackChanges=this.lazyLoad=false;this._entitySetReferences={};this._storageModel=[];var b=this;b._isOK=false;var c=this._successInitProvider; -this._successInitProvider=function(a){a instanceof $data.EntityContext?c(b):c(b,a)};this._storageModel.getStorageModel=function(a){a=Container.resolveName(a);return b._storageModel[a]};if(typeof a.name==="string")a.name=[a.name];var d=[].concat(a.name),e=$data.typeSystem.createCallbackSetting({success:this._successInitProvider,error:this._successInitProvider});this._initStorageModelSync();b._initializeEntitySets(b.getType());$data.StorageProviderLoader.load(d,{success:function(c){b.storageProvider= -new c(a,b);b.storageProvider.setContext(b);b.stateManager=new $data.EntityStateManager(b);var d=b.getType();if(c.name in d._storageModelCache)b._storageModel=d._storageModelCache[c.name];else{b._initializeStorageModel();d._storageModelCache[c.name]=b._storageModel}a&&a.user&&Object.defineProperty(b,"user",{value:a.user,enumerable:true});a&&a.checkPermission&&Object.defineProperty(b,"checkPermission",{value:a.checkPermission,enumerable:true});b._initializeStore(e)},error:function(){e.error("Provider fallback failed!")}}); -this.addEventListener=function(a,b){var c="on"+a;c in this||(this[c]=new $data.Event(a,this));this[c].attach(b)};this.removeEventListener=function(a,b){var c="on"+a;c in this&&this[c].detach(b)};this.raiseEvent=function(a,b){var c="on"+a;c in this&&this[c].fire(b)};this.ready=this.onReady({success:$data.defaultSuccessCallback,error:function(){$data.PromiseHandler!==$data.PromiseHandlerBase?$data.defaultErrorCallback.apply(this,arguments):$data.Trace.error(arguments)}})},beginTransaction:function(a, -b,c){function d(a){Object.isNullOrUndefined(a)||(typeof a==="boolean"?g=a:Array.isArray(a)?e=a:f=a)}var e=null,f=null,g=false;d(a);d(b);d(c);a=new $data.PromiseHandler;f=a.createCallback(f);this.storageProvider._beginTran(e,g,f);return a.getPromise()},_isReturnTransaction:function(a){return a instanceof $data.Base||a==="returnTransaction"},_applyTransaction:function(a,b,c,d,e){if(e===true)if(d instanceof $data.Transaction){Array.prototype.push.call(c,d);b.apply(a,c)}else this.beginTransaction(function(d){Array.prototype.push.call(c, -d);b.apply(a,c)});else b.apply(a,c)},getDataType:function(a){if(typeof a=="string"){var b=this[a];if(b===void 0||b===null)b=eval(a);return b}return a},_initializeEntitySets:function(a){for(var b=0,c=this._storageModel.length;b-1&&Object.isNullOrUndefined(e.inverseProperty)){var g=JSON.parse(JSON.stringify(e));g.dataType=f;c[e.name]=g}else{this._buildDbType_navigationPropertyComplite(e,f,b);if((f===$data.Array||f.isAssignableTo&&f.isAssignableTo($data.EntitySet))&&e.inverseProperty&&e.inverseProperty!=="$$unbound")this._buildDbType_Collection_OneManyDefinition(c,b,f,e);else if(e.inverseProperty)if(e.inverseProperty==="$$unbound")f===$data.Array?this._buildDbType_Collection_OneManyDefinition(c, -b,f,e):this._buildDbType_ElementType_OneManyDefinition(c,b,f,e);else(g=f.memberDefinitions.getMember(e.inverseProperty))?g.elementType?Container.resolveType(g.elementType)===b.LogicalType?this._buildDbType_ElementType_OneManyDefinition(c,b,f,e):typeof intellisense==="undefined"&&Guard.raise(new Exception("Inverse property not valid, refereed item element type not match: "+b.LogicalTypeName,", property: "+e.name)):this._buildDbType_ElementType_OneOneDefinition(c,b,f,e):typeof intellisense==="undefined"&& -Guard.raise(new Exception("Inverse property not valid"));else this._buildDbType_addComplexTypePropertyDefinition(c,b,f,e)}}this._buildDbType_modifyInstanceDefinition(c,b,this);d={};d.convertTo=this._buildDbType_generateConvertToFunction(b,this);this._buildDbType_modifyClassDefinition(d,b,this);b.PhysicalType=$data.Class.define(b.PhysicalTypeName,$data.Entity,b.LogicalType.container,c,d)}},_initializeActions:function(a,b,c){if(c&&c.actions)for(var d=Object.keys(c.actions),e=0;e1&&typeof intellisense!=="undefined"&&Guard.raise(new Exception("More than one inverse property refer to this member definition: "+a.name+ -", type: "+Container.resolveName(c.LogicalType)));if(c=d.pop())a.inverseProperty=c.name}}},_buildDbType_generateConvertToFunction:function(){return function(a){return a}},_buildDbType_modifyInstanceDefinition:function(){},_buildDbType_modifyClassDefinition:function(){},_buildDbType_addComplexTypePropertyDefinition:function(a,b,c,d){this._addNavigationPropertyDefinition(a,d,d.name,$data.MemberTypes.complexProperty);a=this._createComplexElement(b.LogicalType,"",d.name,c,"","");b.ComplexTypes[d.name]= -a;b.ComplexTypes.push(a)},_buildDbType_Collection_OneManyDefinition:function(a,b,c,d){c=Container.resolveType(d.elementType);(c===void 0||c===null)&&typeof intellisense==="undefined"&&Guard.raise(new Exception("Element type definition error","Field definition",d));(c=this._storageModel.getStorageModel(c))||typeof intellisense==="undefined"&&Guard.raise(new Exception("No EntitySet definition for the following element type","Field definition",d));this._addNavigationPropertyDefinition(a,d,d.name);a= -this._addAssociationElement(b.LogicalType,d.inverseProperty==="$$unbound"?"$$unbound":"0..1",d.name,c.LogicalType,"*",d.inverseProperty);b.Associations[d.name]=a;b.Associations.push(a)},_buildDbType_ElementType_OneManyDefinition:function(a,b,c,d){c=Container.resolveType(d.dataType);(c===void 0||c===null)&&typeof intellisense==="undefined"&&Guard.raise(new Exception("Element type definition error","Field definition",d));(c=this._storageModel.getStorageModel(c))||typeof intellisense==="undefined"&& -Guard.raise(new Exception("No EntitySet definition for the following element type","Field definition",d));this._addNavigationPropertyDefinition(a,d,d.name);a=this._addAssociationElement(b.LogicalType,d.inverseProperty==="$$unbound"?"$$unbound":"*",d.name,c.LogicalType,"0..1",d.inverseProperty);b.Associations[d.name]=a;b.Associations.push(a)},_buildDbType_ElementType_OneOneDefinition:function(a,b,c,d){c=Container.resolveType(d.dataType);(c===void 0||c===null)&&typeof intellisense==="undefined"&&Guard.raise(new Exception("Element type definition error", -"Field definition",d));(c=this._storageModel.getStorageModel(c))||typeof intellisense==="undefined"&&Guard.raise(new Exception("No EntitySet definition following element type","Field definition",d));!c.LogicalType.memberDefinitions.getMember(d.inverseProperty).required&&!d.required&&typeof intellisense==="undefined"&&typeof intellisense==="undefined"&&Guard.raise(new Exception("In one to one connection, one side must required!","One to One connection",d));this._addNavigationPropertyDefinition(a,d, -d.name);a=this._addAssociationElement(b.LogicalType,d.required?"0..1":"1",d.name,c.LogicalType,d.required?"1":"0..1",d.inverseProperty);b.Associations[d.name]=a;b.Associations.push(a)},_addNavigationPropertyDefinition:function(a,b,c,d){var e=JSON.parse(JSON.stringify(b));e.dataType=$data.EntitySet;e.notMapped=true;e.kind=d?d:$data.MemberTypes.navProperty;e.association=c;a[b.name]=e},_addAssociationElement:function(a,b,c,d,e,f){return new $data.Association({From:a.name,FromType:a,FromMultiplicity:b, -FromPropertyName:c,To:d.name,ToType:d,ToMultiplicity:e,ReferentialConstraint:[],ToPropertyName:f})},_createComplexElement:function(a,b,c,d,e,f){return new $data.ComplexType({From:a.name,FromType:a,FromMultiplicity:b,FromPropertyName:c,To:d.name,ToType:d,ToMultiplicity:e,ReferentialConstraint:[],ToPropertyName:f})},_successInitProvider:function(a,b){if(a instanceof $data.EntityContext&&a._isOK!==void 0)if(b){a._isOK=b;if(a.onReadyFunction){for(c=0;c0;){for(var i=[],j=0;j0){f.error(h);return e}for(var h=$data.Access.None,t={},n=[],j=0;j0&&(g=g+" &&");g=g+(" e."+j.name+" == this.key"+i);h["key"+i]=a[j.name]}g=g+"; }";a=this.getEntitySetFromElementType(a.getType());return a.map("function (e) { return e."+b.name+" }").single(g,h,c,d)}g="function (e) { return";h={};for(i=0;i0&&(g=g+" &&");g=g+(" e."+b.inverseProperty+"."+j.name+" == this.key"+i);h["key"+i]=a[j.name]}g=g+"; }";a=this.getEntitySetFromElementType(e); -return a.filter(g,h).toArray(c,d)},getTraceString:function(a){return this.storageProvider.getTraceString(new $data.Query(a.expression,a.defaultType,this))},log:function(){},resolveBinaryOperator:function(a,b,c){return this.storageProvider.resolveBinaryOperator(a,b,c)},resolveUnaryOperator:function(a,b,c){return this.storageProvider.resolveUnaryOperator(a,b,c)},resolveFieldOperation:function(a,b,c){return this.storageProvider.resolveFieldOperation(a,b,c)},resolveSetOperations:function(a,b,c){return this.storageProvider.resolveSetOperations(a, -b,c)},resolveTypeOperations:function(a,b,c){return this.storageProvider.resolveTypeOperations(a,b,c)},resolveContextOperations:function(a,b,c){return this.storageProvider.resolveContextOperations(a,b,c)},_generateServiceOperationQueryable:function(a,b,c,d){typeof console!=="undefined"&&console.log&&console.log("Obsolate: _generateServiceOperationQueryable, $data.EntityContext");for(var e=[],f=0;f0?$data.EntityState.Modified: -$data.EntityState.Unchanged;else{typeof b==="string"&&(b=$data.EntityAttachMode[b]);d=b||$data.EntityAttachMode[$data.EntityAttachMode.defaultMode];if(typeof d==="function")d.call($data.EntityAttachMode,c);else{c.entityState=$data.EntityState.Unchanged;c.changedProperties=void 0}}c.context=this.entityContext;this._trackEntity(c)},detach:function(a){var b=a;a instanceof $data.EntityWrapper?b=a.getEntity():a instanceof this.createNew||(b=new this.createNew(a));for(var c,d=this.entityContext.stateManager.trackedEntities, -e=0;e0?$data.EntityState.Modified:$data.EntityState.Unchanged},Default:function(a){a.entityState=$data.EntityState.Unchanged;a.changedProperties=void 0}}); -$data.Class.define("$data.EntityStateManager",null,null,{constructor:function(a){this.entityContext=null;this.trackedEntities=[];this.init(a)},init:function(a){this.entityContext=a},reset:function(){this.trackedEntities=[]}},null); -$data.Class.define("$data.ItemStoreClass",null,null,{constructor:function(){var a=this;a.itemStoreConfig={aliases:{},contextTypes:{}};a.resetStoreToDefault("local",true);$data.addStore=function(){return a.addItemStoreAlias.apply(a,arguments)};$data.implementation=a.implementation;$data.Entity.addMember("storeToken",{get:function(){if(this.storeConfigs&&this.storeConfigs["default"])return this.storeConfigs.stores[this.storeConfigs["default"]]},set:function(b){a._setTypeStoreConfig(this,"default",b)}}, -true)},itemStoreConfig:{},addItemStoreAlias:function(a,b,c){var d=this,e=new $data.PromiseHandler,f=e.createCallback();if("string"===typeof a){if("object"===typeof b&&"factory"in b){var g=Container.resolveType(b.typeName);d.itemStoreConfig.aliases[a]=b.factory;d.itemStoreConfig.contextTypes[a]=g;c&&(d.itemStoreConfig["default"]=a);f.success();return e.getPromise()}if("function"===typeof b){if((g=b())&&g instanceof $data.EntityContext){f.success(g);g=e.getPromise()}return g.then(function(g){if(typeof g=== -"function")return d.addItemStoreAlias(a,g,c);if(g instanceof $data.EntityContext)return g.onReady().then(function(e){d.itemStoreConfig.aliases[a]=b;d.itemStoreConfig.contextTypes[a]=e.getType();c&&(d.itemStoreConfig["default"]=a);return e});e=new $data.PromiseHandler;f=e.createCallback();f.error(new Exception("factory dont have context instance","Invalid arguments"));return e.getPromise()})}}f.error(new Exception("Name or factory missing","Invalid arguments"));return e.getPromise()},resetStoreToDefault:function(a, -b){this.itemStoreConfig.aliases[a]=this._getDefaultItemStoreFactory;delete this.itemStoreConfig.contextTypes[a];b&&(this.itemStoreConfig["default"]=a)},_setStoreAlias:function(a,b){if("object"===typeof b&&!a.storeToken)a.storeToken=b;return a},_getStoreAlias:function(a,b){var c;if(a instanceof $data.Entity){if(c=b||a.storeToken)return c;c=a.getType()}else c=a;return b||(c.storeConfigs?c.storeConfigs["default"]:void 0)||c.storeToken},_getStoreContext:function(a,b,c){a=this._getContextPromise(a,b); -if(!a||a instanceof $data.EntityContext){b=new $data.PromiseHandler;b.createCallback().success(a);a=b.getPromise()}return a.then(function(a){if(a instanceof $data.EntityContext)return a.onReady();if(c)return null;a=new $data.PromiseHandler;a.createCallback().error(new Exception("factory return type error","Error"));return a.getPromise()})},_getContextPromise:function(a,b){if(a&&"object"===typeof a&&"function"===typeof a.factory)return a.factory(b);if(a&&"object"===typeof a&&"object"===typeof a.args&& -"string"===typeof a.typeName){b=Container.resolveType(a.typeName);return new b(JSON.parse(JSON.stringify(a.args)))}return a&&"string"===typeof a&&b.storeConfigs&&b.storeConfigs.stores[a]&&typeof b.storeConfigs.stores[a].factory==="function"?b.storeConfigs.stores[a].factory():a&&"string"===typeof a&&b.storeConfigs&&b.storeConfigs.stores[a]?this._getDefaultItemStoreFactory(b,b.storeConfigs.stores[a]):a&&"string"===typeof a&&this.itemStoreConfig.aliases[a]?this.itemStoreConfig.aliases[a](b):a&&"function"=== -typeof a?a():this.itemStoreConfig.aliases[this.itemStoreConfig["default"]](b)},_getStoreEntitySet:function(a,b){var c=this._getStoreAlias(b,a),d="function"===typeof b?b:b.getType();return this._getStoreContext(c,d).then(function(a){a=a.getEntitySetFromElementType(d);if(!a){a=new $data.PromiseHandler;a.createCallback().error("EntitySet not exist for "+d.fullName);return a.getPromise()}return a})},_getDefaultItemStoreFactory:function(a,b){if(a){var c="function"===typeof a?a:a.getType(),d=$data.Container.resolveName(c)+ -"_items",d=d.replace(/\./g,"_"),e=$data.typeSystem.extend({collectionName:b&&b.collectionName?b.collectionName:"Items",tableName:d,initParam:{provider:"local",databaseName:d}},b),f={};f[e.collectionName]={type:$data.EntitySet,elementType:c};if(e.tableName)f[e.collectionName].tableName=e.tableName;c=new ($data.EntityContext.extend(d,f))(e.initParam);if(b&&typeof b==="object")b.factory=c._storeToken.factory;return c}},implementation:function(a,b){var c=$data.ItemStore,d;typeof b==="string"?b=c.itemStoreConfig.contextTypes[b]: -b instanceof $data.EntityContext?b=b.getType():typeof b==="function"&&b.isAssignableTo||(b=c.itemStoreConfig.contextTypes[c.itemStoreConfig["default"]]);b&&(d=c._resolveFromContext(b,a));d||(d=Container.resolveType(a));return d},_resolveFromContext:function(a,b){for(var c=a.memberDefinitions.getPublicMappedProperties(),d=0;d1&&b&&"object"===typeof b){for(var d="",e={},f=0;f0&&(d=d+" && ");var g=c[f],d=d+("it."+g.name+" == this."+g.name);e[g.name]=b[g.name]}return{predicate:d,thisArgs:e}}if(c.length=== -1)return{predicate:"it."+c[0].name+" == this.value",thisArgs:{value:b}};throw"invalid keys";},_getKeyObjectFromEntity:function(a,b){var c,d=b.memberDefinitions.getKeyProperties();if(d.length===1)c=a&&typeof a==="object"?a[d[0].name]:a;else{c={};for(var e=0;e0){$data.Trace.log(a+" provider failed to load, trying to fallback to "+b+" provider(s)");d.find(b,c)}else{$data.Trace.log(a+" provider failed to load");c.error()}})}},getUrl:function(a){var b=document.querySelector('script[src$="jaydata.min.js"]'),c=document.querySelector('script[src$="jaydata.js"]');return b? -b.src.substring(0,b.src.lastIndexOf("/")+1)+"jaydataproviders/"+a+"Provider.min.js":c?c.src.substring(0,c.src.lastIndexOf("/")+1)+"jaydataproviders/"+a+"Provider.js":"jaydataproviders/"+a+"Provider.js"},loadScript:function(a,b,c){if(a){var d;if(window.XMLHttpRequest)d=new XMLHttpRequest;else if(window.ActiveXObject!==void 0)d=new ActiveXObject("MsXml2.XmlHttp");else{$data.Trace.log("XMLHttpRequest or MsXml2.XmlHttp ActiveXObject not found");c(false);d=void 0}d.onreadystatechange=function(){$data.Trace.log("HTTP request is in state: "+ -d.readyState);if(d.readyState==4)if(d.status==200||d.status==304){$data.Trace.log("HTTP request succeeded");$data.Trace.log("HTTP request response text: "+d.responseText);eval.call(window,d.responseText);typeof c==="function"?c(true):$data.Trace.log("Callback function is undefined")}else{$data.Trace.log("HTTP request status: ",d.status);typeof c==="function"?c(false):$data.Trace.log("Callback function is undefined")}};d.open("GET",a,true);d.send(null)}else c(false)},loadScriptElement:function(a,b, -c){function d(){$data.Trace.log("Script element watcher iteration "+h);if($data.RegisteredStorageProviders[b]){$data.Trace.log(b+" provider registered");c(true)}else{h--;if(h>0){$data.Trace.log("Script element watcher next iteration");setTimeout(d,g)}else{$data.Trace.log("Script element loader failed");c(false)}}}var e=document.getElementsByTagName("head")[0]||document.documentElement,f=document.createElement("script");f.type="text/javascript";f.src=a;$data.Trace.log("Appending child "+f+" to "+e); -e.appendChild(f);var g=this.scriptLoadInterval||50,h=Math.ceil(this.scriptLoadTimeout/g);$data.Trace.log("Script element watcher iterating "+h+" times");setTimeout(d,g)},loadNpmModule:function(a,b,c){var d=null;try{require(this.npmModules[a]);d=$data.RegisteredStorageProviders[a];$data.Trace.log("NPM module loader successfully registered "+a+" provider")}catch(e){$data.Trace.log("NPM module loader failed for "+a+" provider")}d?c.success(d):b.length>0?this.find(b,c):c.error()},virtualProviders:{type:$data.Array, -value:{local:{fallbacks:["webSql","indexedDb","LocalStore"]}}},getVirtual:function(a){return this.virtualProviders[a]?[].concat(this.virtualProviders[a].fallbacks):a}});$data.StorageProviderLoader=new $data.StorageProviderLoaderBase;$data.storageProviders={DbCreationType:{Merge:10,DropTableIfChanged:20,DropTableIfChange:20,DropAllExistingTables:30,ErrorIfChange:40,DropDbIfChange:50}};$data.ConcurrencyMode={Fixed:"fixed",None:"none"}; -$data.Class.define("$data.StorageProviderBase",null,null,{constructor:function(a){this.providerConfiguration=a||{};this.name=this.getType().name;if($data.RegisteredStorageProviders)for(var a=Object.keys($data.RegisteredStorageProviders),b=0;b0;){f=[].concat(e);e=[];for(g=0;g -0&&d.push(g)}return d},getTraceString:function(){Guard.raise("Pure class")},setContext:function(a){this.context=a},_buildContinuationFunction:function(a,b){if(Array.isArray(b.result)){b.result.next=this._buildPagingMethod(a,b,"next");b.result.prev=this._buildPagingMethod(a,b,"prev")}},_buildPagingMethod:function(a,b,c){return function(d){var e=new $data.PromiseHandler,d=e.createCallback(d),f=(new $data.Expressions.ContinuationExpressionBuilder(c)).compile(b);if(f.expression){f=Container.createQueryable(a, -f.expression);f.defaultType=b.defaultType;a.executeQuery(f,d)}else d.error(new Exception(f.message,"Invalid Operation",f));return e.getPromise()}},buildDbType_modifyInstanceDefinition:function(a,b){var c=function(b,c){var d;if(c){d=JSON.parse(JSON.stringify(a[c]));d.kind=b.kind;d.name=b.name;d.notMapped=false}else d=JSON.parse(JSON.stringify(b));d.dataType=Container.resolveType(b.dataType);d.type=d.dataType;d.key=false;d.computed=false;return d},d=function(a,b,c,d,i){var j={};j[a.name]=c;j[b.name]= -i?i:d+"__"+c;return j};b.Associations&&b.Associations.forEach(function(b){var f=false,g=b.FromType,h=b.ToType,i=b.ToPropertyName,j=b.FromType.getMemberDefinition(b.FromPropertyName),l=[];j&&typeof j.keys==="string"&&j.keys?l=[j.keys]:j&&Array.isArray(j.keys)&&(l=[].concat(j.keys));b.ReferentialConstraint=b.ReferentialConstraint||[];if(b.FromMultiplicity=="*"&&b.ToMultiplicity=="0..1"||b.FromMultiplicity=="0..1"&&b.ToMultiplicity=="1"){g=b.ToType;h=b.FromType;i=b.FromPropertyName;f=true}g.memberDefinitions.getPublicMappedProperties().filter(function(a){return a.key}).forEach(function(j, -q){var n=d(g,h,j.name,i,l[q]);if(f){a[n[h.name]]=c(j,i);var z=h.getMemberDefinition(l[q]);if(z){z.isDependentProperty=true;z.navigationPropertyName=b.FromPropertyName}}b.ReferentialConstraint.push(n)},this)},this);b.ComplexTypes&&b.ComplexTypes.forEach(function(b){b.ReferentialConstraint=b.ReferentialConstraint||[];b.ToType.memberDefinitions.getPublicMappedProperties().forEach(function(f){a[b.FromPropertyName+"__"+f.name]=c(f);b.ReferentialConstraint.push(d(b.ToType,b.FromType,f.name,b.FromPropertyName))}, -this)},this)},buildDbType_generateConvertToFunction:function(a){return function(b){var c=new a.PhysicalType;c.entityState=b.entityState;a.PhysicalType.memberDefinitions.getPublicMappedProperties().forEach(function(a){b[a.name]!==void 0&&(c[a.name]=b[a.name])},this);a.Associations&&a.Associations.forEach(function(a){if(a.FromMultiplicity=="*"&&a.ToMultiplicity=="0..1"||a.FromMultiplicity=="0..1"&&a.ToMultiplicity=="1"){var e=b[a.FromPropertyName];e!==void 0&&a.ReferentialConstraint.forEach(function(b){c[b[a.From]]= -e!==null?e[b[a.To]]:null},this)}},this);a.ComplexTypes&&a.ComplexTypes.forEach(function(a){var e=b[a.FromPropertyName];e!==void 0&&a.ReferentialConstraint.forEach(function(b){c[b[a.From]]=e!==null?e[b[a.To]]:null},this)},this);return c}},bulkInsert:function(a,b,c,d){d.error(new Exception("Not Implemented"))},supportedFieldOperations:{value:{length:{dataType:"number",allowedIn:"filter, map"},substr:{dataType:"string",allowedIn:"filter",parameters:[{name:"startFrom",dataType:"number"},{name:"length", -dataType:"number"}]},toLowerCase:{dataType:"string"}},enumerable:!0,writable:!0},resolveFieldOperation:function(a,b,c){var d=this.supportedFieldOperations[a];if(Array.isArray(d)){for(var e=0;e0&&this.DefaultSelection(b,a.expression.entityType,c)}if(a.expression instanceof $data.Expressions.EntityExpression)this.DefaultSelection(b, -a.expression.entityType);else if(a.expression instanceof $data.Expressions.EntitySetExpression){b.modelBinderConfig.$type=$data.Array;b.modelBinderConfig.$item={};b.selectModelBinderProperty("$item");this.DefaultSelection(b,a.expression.elementType);b.popModelBinderProperty()}},VisitEntityFieldExpression:function(a,b){this.Visit(a.source,b);this.Visit(a.selector,b)},VisitMemberInfoExpression:function(a,b){b.modelBinderConfig.$type=a.memberDefinition.type;if(a.memberDefinition.storageModel&&a.memberName in -a.memberDefinition.storageModel.ComplexTypes)this._addPropertyToModelBinderConfig(Container.resolveType(a.memberDefinition.type),b);else if(!b.modelBinderConfig.$type||!Container.resolveType(b.modelBinderConfig.$type).isAssignableTo||!Container.resolveType(b.modelBinderConfig.$type).isAssignableTo($data.Entity))b.modelBinderConfig.$source=a.memberName},VisitEntitySetExpression:function(a,b){if(a.source instanceof $data.Expressions.EntityExpression){this.Visit(a.source,b);this.Visit(a.selector,b)}}, -VisitComplexTypeExpression:function(a,b){this.Visit(a.source,b);this.Visit(a.selector,b);if("$selector"in b.modelBinderConfig&&b.modelBinderConfig.$selector.length>0)if(b.modelBinderConfig.$selector instanceof $data.Array){var c=b.modelBinderConfig.$selector[1];b.modelBinderConfig.$selector[0]=c+"."+a.selector.memberName+".results";b.modelBinderConfig.$selector[1]=c+"."+a.selector.memberName}else b.modelBinderConfig.$selector=b.modelBinderConfig.$selector+("."+a.selector.memberName);else b.modelBinderConfig.$selector= -this._isoDataProvider?["json:"+a.selector.memberName+".results","json:"+a.selector.memberName]:"json:"+a.selector.memberName},VisitEntityExpression:function(a,b){this.Visit(a.source,b)},VisitAssociationInfoExpression:function(a,b){if("$selector"in b.modelBinderConfig&&b.modelBinderConfig.$selector.length>0)if(b.modelBinderConfig.$selector instanceof $data.Array){var c=b.modelBinderConfig.$selector[1];b.modelBinderConfig.$selector[0]=c+"."+a.associationInfo.FromPropertyName+".results";b.modelBinderConfig.$selector[1]= -c+"."+a.associationInfo.FromPropertyName}else b.modelBinderConfig.$selector=b.modelBinderConfig.$selector+("."+a.associationInfo.FromPropertyName);else b.modelBinderConfig.$selector=this._isoDataProvider?["json:"+a.associationInfo.FromPropertyName+".results","json:"+a.associationInfo.FromPropertyName]:"json:"+a.associationInfo.FromPropertyName;if(this.mapping&&this.mapping.length>0)this.mapping=this.mapping+".";this.mapping=this.mapping+a.associationInfo.FromPropertyName},VisitObjectLiteralExpression:function(a, -b){b.modelBinderConfig.$type=$data.Object;a.members.forEach(function(a){this.Visit(a,b)},this)},VisitObjectFieldExpression:function(a,b){b.selectModelBinderProperty(a.fieldName);a.expression instanceof $data.Expressions.EntityExpression||a.expression instanceof $data.Expressions.EntitySetExpression?this.VisitEntityAsProjection(a,b):this.Visit(a.expression,b);b.popModelBinderProperty()}}); -$data.Class.define("$data.Authentication.AuthenticationBase",null,null,{constructor:function(a){this.configuration=a||{};this.Authenticated=false},Login:function(){Guard.raise("Pure class")},Logout:function(){Guard.raise("Pure class")},CreateRequest:function(){Guard.raise("Pure class")}},null); -$data.Class.define("$data.Authentication.Anonymous",$data.Authentication.AuthenticationBase,null,{constructor:function(a){this.configuration=a||{};this.Authenticated=false},Login:function(){},Logout:function(){},CreateRequest:function(a){$data.ajax(a)}},null); -$data.Class.define("$data.Authentication.FacebookAuth",$data.Authentication.AuthenticationBase,null,{constructor:function(a){this.configuration=$data.typeSystem.extend({Url_code:"",type_code:"",scope:"",Url_token:"",type_token:"",access_token:"",app_id:""},a)},Login:function(a){if(!this.Authenticated){var b=this;b.configuration.stateCallbacks=a||{};$data.ajax({url:this.configuration.Url_code,data:"type="+b.configuration.type_code+"&client_id="+b.configuration.app_id+"&scope="+b.configuration.scope, -type:"POST",dataType:"json",success:function(a){typeof b.configuration.stateCallbacks.pending=="function"&&b.configuration.stateCallbacks.pending(a);b._processRequestToken(a);b.Authenticated=true},error:function(){typeof b.configuration.stateCallbacks.error=="function"&&b.configuration.stateCallbacks.error(arguments)}})}},Logout:function(){this.Authenticated=false},CreateRequest:function(a){if(a){if(a.url.indexOf("access_token=")===-1&&a.url&&this.Authenticated){var b="?";a.url.indexOf(b)>0&&(b="&"); -if(this.configuration.access_token)a.url=a.url+b+"access_token="+this.configuration.access_token}$data.ajax(a)}},_processRequestToken:function(a){var b=this;$data.ajax({url:b.configuration.Url_token,data:"type="+b.configuration.type_token+"&client_id="+b.configuration.app_id+"&code="+a.code,type:"POST",dataType:"json",success:function(a){b.configuration.access_token=a.access_token;typeof b.configuration.stateCallbacks.success=="function"&&b.configuration.stateCallbacks.success(a)},error:function(c){var d= -eval("("+c.responseText+")");d.error&&(d.error.message=="authorization_pending"?setTimeout(function(){b._processRequestToken(a)},2E3):typeof b.configuration.stateCallbacks.abort=="function"&&b.configuration.stateCallbacks.abort(arguments))}})}},null); -$data.Class.define("$data.Authentication.BasicAuth.BasicAuth",$data.Authentication.AuthenticationBase,null,{constructor:function(a){this.configuration=$data.typeSystem.extend({Username:"",Password:""},a)},Login:function(a){a&&typeof a.pending=="function"&&a.pending()},Logout:function(){},CreateRequest:function(a){if(a){var b=this,c=a.beforeSend;a.beforeSend=function(a){a.setRequestHeader("Authorization","Basic "+b.__encodeBase64(b.configuration.Username+":"+b.configuration.Password));typeof c=="function"&& -c(a)};$data.ajax(a)}},__encodeBase64:function(a){input=a;var a="",b,c,d="",e,f,g="",h=0;do{b=input.charCodeAt(h++);c=input.charCodeAt(h++);d=input.charCodeAt(h++);e=b>>2;b=(b&3)<<4|c>>4;f=(c&15)<<2|d>>6;g=d&63;isNaN(c)?f=g=64:isNaN(d)&&(g=64);a=a+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(e)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(b)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(f)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(g)}while(h< -input.length);return a}},null); -$data.Class.define("$data.MetadataLoaderClass",null,null,{load:function(a,b,c){var d={EntityBaseClass:"$data.Entity",ContextBaseClass:"$data.EntityContext",AutoCreateContext:false,DefaultNamespace:("ns"+Math.random()).replace(".","")+a.replace(/[^\w]/g,"_"),ContextInstanceName:"context",EntitySetBaseClass:"$data.EntitySet",CollectionBaseClass:"Array",url:a,user:void 0,password:void 0,withCredentials:void 0,httpHeaders:void 0,typeFilter:"",navigation:true,generateKeys:true,dependentRelationsOnly:false}; -$data.typeSystem.extend(d,c||{});if(d.DefaultNamespace&&d.DefaultNamespace.lastIndexOf(".")!==d.DefaultNamespace.length-1)d.DefaultNamespace=d.DefaultNamespace+".";this.factoryCache=this.factoryCache||{};b=$data.typeSystem.createCallbackSetting(b);if(a in this.factoryCache)b.success.apply({},this.factoryCache[a]);else{if(d.url){d.SerivceUri=d.url.replace("/$metadata","");d.metadataUri=d.url.indexOf("/$metadata")===-1?d.url.replace(/\/+$/,"")+"/$metadata":d.url}else b.error("metadata url is missing"); -var e=this;e._loadXMLDoc(d,function(a,c){if(c.statusCode<200||c.statusCode>299)b.error(c);else{var h=e._findVersion(a);if(e.xsltRepoUrl){console.log("XSLT: "+e.xsltRepoUrl+e._supportedODataVersionXSLT);e._loadXMLDoc({metadataUri:e.xsltRepoUrl+e._supportedODataVersionXSLT,user:d.user,password:d.password,httpHeaders:d.httpHeaders},function(c,g){if(g.statusCode<200||g.statusCode>299)b.error(g);else{var l=g.responseText,l=l.replace('xmlns:edm="@@VERSIONNS@@"','xmlns:edm="'+h.ns+'"'),l=l.replace("@@VERSION@@", -h.version);if(window.ActiveXObject===void 0)c=(new DOMParser).parseFromString(l,"text/xml");else{c=new ActiveXObject("Microsoft.XMLDOM");c.async=false;c.loadXML(l)}e._transform(b,h,a,c,d)}})}else e._transform(b,h,a,void 0,d)}})}},debugMode:{type:"bool",value:!1},xsltRepoUrl:{type:"string",value:""},createFactoryFunc:function(a,b,c){return function(d){if(a){d=$data.typeSystem.extend({name:"oData",oDataServiceHost:b.SerivceUri,user:b.user,password:b.password,withCredentials:b.withCredentials,maxDataServiceVersion:c.maxVersion|| -"3.0"},d);return new a(d)}return null}},_transform:function(a,b,c,d,e){c=this._processResults(e.url,b,c,d,e);try{eval(c)}catch(f){a.error(new Exception("SyntaxError","Unexpected model",[f,c]));return}var g;if(!$data.generatedContexts||!(g=$data.generatedContexts.pop()))a.error(new Exception("No context found in service","Not found",[e,c]));else{b=this.createFactoryFunc(g,e,b);this.factoryCache[e.url]=[b,g];b.type=g;if(this.debugMode){b.codeText=c;a.success(b,g,c)}else a.success(b,g)}},_loadXMLDoc:function(a, -b){var c=this;if($data.postMessageODataHandler){if(a.user&&a.password&&(!a.httpHeaders||a.httpHeaders&&!a.httpHeaders.Authorization)){httpHeader=httpHeader||{};httpHeader.Authorization="Basic "+this.__encodeBase64(a.user+":"+a.password)}$data.postMessageODataHandler.requestProxy({url:a.metadataUri,httpHeaders:a.httpHeaders,success:function(a){var c;if(typeof module!=="undefined"&&typeof require!=="undefined")c=a.responseText;else if(window.ActiveXObject){c=new ActiveXObject("Microsoft.XMLDOM");c.async= -"false";c.loadXML(a.responseText)}else c=(new DOMParser).parseFromString(a.responseText,"text/xml");b(c,a)},error:function(){c._loadXHTTP_XMLDoc(a,b)}})}else this._loadXHTTP_XMLDoc(a,b)},_loadXHTTP_XMLDoc:function(a,b){var c=new XMLHttpRequest;c.open("GET",a.metadataUri,true);a.httpHeaders&&Object.keys(a.httpHeaders).forEach(function(b){c.setRequestHeader(b,a.httpHeaders[b])});c.onreadystatechange=function(){c.readyState===4&&b(c.responseXML||c.responseText,{requestUri:a.metadataUri,statusCode:c.status, -statusText:c.statusText,responseText:c.responseText})};a.user&&a.password&&(!a.httpHeaders||a.httpHeaders&&!a.httpHeaders.Authorization)&&c.setRequestHeader("Authorization","Basic "+this.__encodeBase64(a.user+":"+a.password));c.send("")},_processResults:function(a,b,c,d,e){var f=this.getCurrentXSLTVersion(b,c);e.typeFilter=this._prepareTypeFilter(c,b,e);if(window.ActiveXObject!==void 0){var a=new ActiveXObject("Msxml2.XSLTemplate.6.0"),g=new ActiveXObject("Msxml2.FreeThreadedDOMDocument.6.0");g.async= -false;d?g.load(d):g.loadXML(f);if(g.parseError.errorCode==0){a.stylesheet=g;d=new ActiveXObject("Msxml2.DOMDocument.6.0");d.async=false;d.load(c);if(d.parseError.errorCode==0){c=a.createProcessor();c.input=d;c.addParameter("SerivceUri",e.SerivceUri);c.addParameter("EntityBaseClass",e.EntityBaseClass);c.addParameter("ContextBaseClass",e.ContextBaseClass);c.addParameter("AutoCreateContext",e.AutoCreateContext);c.addParameter("ContextInstanceName",e.ContextInstanceName);c.addParameter("EntitySetBaseClass", -e.EntitySetBaseClass);c.addParameter("CollectionBaseClass",e.CollectionBaseClass);c.addParameter("DefaultNamespace",e.DefaultNamespace);c.addParameter("MaxDataserviceVersion",b.maxVersion||"3.0");c.addParameter("AllowedTypesList",e.typeFilter);c.addParameter("GenerateNavigationProperties",e.navigation);c.transform();return c.output}}return""}if(typeof document!=="undefined"&&document.implementation&&document.implementation.createDocument){d=d?d:(new DOMParser).parseFromString(f,"text/xml");a=new XSLTProcessor; -a.importStylesheet(d);a.setParameter(null,"SerivceUri",e.SerivceUri);a.setParameter(null,"EntityBaseClass",e.EntityBaseClass);a.setParameter(null,"ContextBaseClass",e.ContextBaseClass);a.setParameter(null,"AutoCreateContext",e.AutoCreateContext);a.setParameter(null,"ContextInstanceName",e.ContextInstanceName);a.setParameter(null,"EntitySetBaseClass",e.EntitySetBaseClass);a.setParameter(null,"CollectionBaseClass",e.CollectionBaseClass);a.setParameter(null,"DefaultNamespace",e.DefaultNamespace);a.setParameter(null, -"MaxDataserviceVersion",b.maxVersion||"3.0");a.setParameter(null,"AllowedTypesList",e.typeFilter);a.setParameter(null,"GenerateNavigationProperties",e.navigation);resultDocument=a.transformToFragment(c,document);return resultDocument.textContent}if(typeof module!=="undefined"&&typeof require!=="undefined"){a=require("node_xslt");return a.transform(a.readXsltString(f),a.readXmlString(c),["SerivceUri","'"+e.SerivceUri+"'","EntityBaseClass","'"+e.EntityBaseClass+"'","ContextBaseClass","'"+e.ContextBaseClass+ -"'","AutoCreateContext","'"+e.AutoCreateContext+"'","ContextInstanceName","'"+e.ContextInstanceName+"'","EntitySetBaseClass","'"+e.EntitySetBaseClass+"'","CollectionBaseClass","'"+e.CollectionBaseClass+"'","DefaultNamespace","'"+e.DefaultNamespace+"'","MaxDataserviceVersion","'"+(b.maxVersion||"3.0")+"'","AllowedTypesList","'"+e.typeFilter+"'","GenerateNavigationProperties","'"+e.navigation+"'"])}},_prepareTypeFilter:function(a,b,c){b="";if(!(typeof a==="object"&&"querySelector"in a&&"querySelectorAll"in -a))return b;var d=[];if(typeof c.typeFilter==="object"&&c.typeFilter){for(var e=Object.keys(c.typeFilter),f=0;f0){i=h.Name.substring(0,h.Name.lastIndexOf("."));g=h.Name.substring(h.Name.lastIndexOf(".")+1)}for(var i=a.querySelectorAll("EntityContainer[Name = '"+ -i+"']"),j=0;j0?b+(a.Name+":"+a.Fields.join(",")+";"):b+(a.Name+";")}}return b},_discoverTypeDependencies:function(a,b,c,d){for(var e=[],f=[],g=[],h=0;h=0&&g.splice(i,1);this._discoverType(a[h],b,e,f,c,d,true,g)}for(h=0;h=0)){console.log("Discover: "+i);var j=i,l="";if(i.lastIndexOf(".")> -0){l=i.substring(0,i.lastIndexOf("."));j=i.substring(i.lastIndexOf(".")+1)}l=b.querySelector("Schema[Namespace = '"+l+"']");if(l!=null){var w=l.querySelector("EntityType[Name = '"+j+"'], ComplexType[Name = '"+j+"']");if(w!=null){c.push(a);d.push(i);if(f&&a.Fields.length>0){var q=w.querySelectorAll("Key PropertyRef");if(q!=null)for(j=0;j=0){q=n.attributes.ToRole.value;n=l.querySelector("Association End[Role = '"+n.attributes.FromRole.value+"']:not([Type = '"+i+"'])");n==null&&(n=l.querySelector("Association End[Role = '"+q+"']:not([Type = '"+i+"'])"));if(n!=null){q=n.attributes.Type.value;g?h.indexOf(q)<0&&d.indexOf(q)<0&&h.push(q):this._discoverType({Name:q,Fields:[]},b,c,d,e,f,false,h)}}}}}}}},_discoverProperyDependencies:function(a,b,c,d){for(var e=[],f=a.map(function(a){return a.Name}), -g=0;g0){j=g.substring(0,g.lastIndexOf("."));i=g.substring(g.lastIndexOf(".")+1)}b=b.querySelector("Schema[Namespace = '"+j+"']");if(b!=null){i=b.querySelector("EntityType[Name = '"+i+"'], ComplexType[Name = '"+i+"']");if(i!=null){c.push(a);if(h){if(f){d=i.querySelectorAll("Key PropertyRef");if(d!= -null)for(c=0;c=0&&a.Fields.push(f)}}}}}},_findVersion:function(a){var b="";if(typeof a==="object"&&"getElementsByTagName"in a){var c="http://schemas.microsoft.com/ado/2008/09/edm",d=a.getElementsByTagName("Schema");d&&(d=d[0]);if(d)d=d.attributes;d&&(d=d.getNamedItem("xmlns"));if(d)c=d.value;(b=a.getElementsByTagName("edmx:DataServices")[0]||a.getElementsByTagName("DataServices")[0])&&(b=b.attributes.getNamedItem("m:MaxDataServiceVersion"));if(b&&c)b=b.value;return{ns:c,version:this._supportedODataVersions[c]|| -"unknown",maxVersion:b||this._maxDataServiceVersions[c||"unknown"]}}if(typeof module!=="undefined"&&typeof require!=="undefined"){b="http://schemas.microsoft.com/ado/2008/09/edm";c="nodejs";for(d in this._supportedODataVersions)if(a.search(RegExp('=0){b=d;c=this._supportedODataVersions[d];break}return{ns:b,version:c,maxVersion:this._maxDataServiceVersions[c||"unknown"]}}},_supportedODataVersions:{value:{"http://schemas.microsoft.com/ado/2006/04/edm":"V1","http://schemas.microsoft.com/ado/2008/09/edm":"V2", -"http://schemas.microsoft.com/ado/2009/11/edm":"V3","http://schemas.microsoft.com/ado/2007/05/edm":"V11","http://schemas.microsoft.com/ado/2009/08/edm":"V22"}},_maxDataServiceVersions:{value:{"http://schemas.microsoft.com/ado/2006/04/edm":"2.0","http://schemas.microsoft.com/ado/2008/09/edm":"2.0","http://schemas.microsoft.com/ado/2009/11/edm":"3.0","http://schemas.microsoft.com/ado/2007/05/edm":"2.0","http://schemas.microsoft.com/ado/2009/08/edm":"2.0"}},_supportedODataVersionXSLT:{value:"JayDataContextGenerator.xslt"}, -getCurrentXSLTVersion:function(a){return this._metadataConverterXSLT.replace("@@VERSIONNS@@",a.ns).replace("@@VERSION@@",a.version)},__encodeBase64:function(a){var b="",c,d,e="",f,g,h="",i=0;do{c=a.charCodeAt(i++);d=a.charCodeAt(i++);e=a.charCodeAt(i++);f=c>>2;c=(c&3)<<4|d>>4;g=(d&15)<<2|e>>6;h=e&63;isNaN(d)?g=h=64:isNaN(e)&&(h=64);b=b+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(f)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(c)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(g)+ -"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(h)}while(i\r\n\r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n Microsoft.Crm.Sdk.Data.Services.Product;Microsoft.Crm.Sdk.Data.Services.LeadAddress:Telephone1,City,UTCOffset;\r\n\r\n \r\n \r\n \r\n \r\n <\!--\r\n create field: @@\r\n --\>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n <\!--\r\n create type: \r\n --\>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n <\!--\r\n createTypeList: \r\n --\>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n <\!--\r\n rem: @@ \r\n --\>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n<\!-- TODO EXSLT node-set --\>\r\n <\!----\>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n/*//////////////////////////////////////////////////////////////////////////////////////\r\n////// Autogenerated by JaySvcUtil.exe http://JayData.org for more info /////////\r\n////// oData @@VERSION@@ /////////\r\n//////////////////////////////////////////////////////////////////////////////////////*/\r\n(function(global, $data, undefined) {\r\n\r\n \r\n\r\n \r\n <\!-- TODO EXSLT node-set--\>\r\n <\!----\>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n <\!----\>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n Info: generating type \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n .extend(\'.\', {\r\n \r\n \r\n \r\n \r\n \r\n , \r\n \r\n \r\n \r\n \r\n \r\n \r\n , \r\n \r\n \r\n \r\n \r\n ,\r\n \r\n ,\r\n \r\n \r\n });\r\n\r\n\r\n\r\n\r\n\r\n .extend(\'\', {\r\n <\!--or (@IsBindable = \'true\' and (@IsAlwaysBindable = \'false\' or @m:IsAlwaysBindable = \'false\' or @metadata:IsAlwaysBindable = \'false\'))--\>\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n ,\r\n \r\n \r\n \r\n \r\n \r\n \r\n ,\r\n \r\n \r\n \r\n \r\n });\r\n\r\n $data.generatedContexts = $data.generatedContexts || [];\r\n $data.generatedContexts.push();\r\n \r\n /*Context Instance*/\r\n = new ({ name:\'oData\', oDataServiceHost: \'\', maxDataServiceVersion: \'\' });\r\n\r\n\r\n\r\n \r\n})(window, $data);\r\n \r\n \r\n\r\n \r\n\r\n \r\n \'\r\n \r\n \': { type: \r\n \r\n \r\n $data.ServiceAction\r\n \r\n \r\n $data.ServiceOperation\r\n \r\n \r\n\r\n \r\n\r\n \r\n \r\n \r\n , params: [\r\n \r\n { name: \'\r\n \r\n \', type: \'\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \' }\r\n , \r\n \r\n ]\r\n\r\n }\r\n \r\n \r\n \r\n , returnType: \r\n \r\n null\r\n $data.Queryable\r\n \r\n \'\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \'\r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n , elementType: \'\r\n \r\n \'\r\n \r\n \r\n \r\n \r\n , method: \'\r\n \r\n \'\r\n \r\n \r\n , \r\n \r\n \r\n \r\n : \r\n \r\n \r\n \r\n , \'\r\n \r\n \r\n \r\n \': \'\r\n \r\n \'\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \'\': { type: , elementType: }\r\n\r\n \r\n \r\n \r\n \r\n , actions: { \r\n \r\n \r\n ,\r\n \r\n \r\n \r\n }\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n true\r\n \r\n \'\': { \'$\':\r\n , \r\n \r\n \'$\':\r\n , \r\n \r\n }\r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \'Array\'\r\n \r\n \r\n \r\n \r\n \'\'\r\n \r\n \r\n \'\'\r\n \r\n \r\n \r\n \r\n \'\'\r\n \r\n \r\n \'\'\r\n \r\n \r\n \r\n\r\n \r\n $data.ConcurrencyMode.\r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n true\r\n \r\n \r\n \r\n\r\n \r\n true \r\n \r\n\r\n \r\n \r\n \r\n Number.POSITIVE_INFINITY\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n true\'\'\r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \'\'\r\n \'\'\r\n \r\n \'$$unbound\'\r\n \r\n \'\'\r\n \r\n \r\n \'\'\r\n \r\n \r\n \'\'\r\n \r\n \r\n \'$$unbound\'\r\n Warning: inverseProperty other side missing: \r\n \r\n \r\n \r\n \r\n \r\n \'\'\r\n true\r\n \r\n \r\n \'\'\r\n \r\n \r\n \'$$unbound\'\r\n \r\n Warning: inverseProperty other side missing: \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n\r\n \r\n\r\n \r\n <\!--!!!!--\>\r\n Warning: .: is an unknown/unprocessed attribued\r\n \r\n <\!--\r\n !!\r\n --\>\r\n\r\n'}}); -$data.MetadataLoader=new $data.MetadataLoaderClass; -$data.service=function(a,b,c){function d(a){switch(typeof a){case "object":typeof a.success==="function"||typeof a.error==="function"?f=a:e=a;break;case "function":f=a}}var e,f;d(b);d(c);if(typeof a==="object"){e=$data.typeSystem.extend(a,e);a=a.url;delete e.url}b=new $data.PromiseHandler;f=b.createCallback(f);$data.MetadataLoader.load(a,{success:function(a){var b=a.type;if(e){var c=e.serviceName||e.storeAlias;c&&"addStore"in $data&&$data.addStore(c,a,e.isDefault===void 0||e.isDefault)}f.success(a, -b)},error:f.error},e);return b.getPromise()}; -(function(a){if(typeof jQuery!=="undefined"){a.Class.define("$data.Deferred",a.PromiseHandlerBase,null,{constructor:function(){this.deferred=new $.Deferred},deferred:{},createCallback:function(b){var b=a.typeSystem.createCallbackSetting(b),c=this;return cbWrapper={success:function(){b.success.apply(c.deferred,arguments);c.deferred.resolve.apply(c.deferred,arguments)},error:function(){Array.prototype.push.call(arguments,c.deferred);b.error.apply(c.deferred,arguments)},notify:function(){b.notify.apply(c.deferred, -arguments);c.deferred.notify.apply(c.deferred,arguments)}}},getPromise:function(){return this.deferred.promise()}},null);a.PromiseHandler=a.Deferred}})($data); -(function(a){a.initService=function(b,c){var d=new a.PromiseHandler,e;if(typeof b==="object"){e=b;var f=e.isSSL||e.isSSL===void 0?"https":"http",g=e.port?":"+e.port:"",b=typeof e.license==="string"&&e.license.toLowerCase()==="business"?e.appId&&e.serviceName?f+"://"+e.appId+".jaystack.net"+g+"/"+e.serviceName:e.url:e.ownerId&&e.appId&&e.serviceName?f+"://open.jaystack.net/"+e.ownerId+"/"+e.appId+"/api/"+e.serviceName:e.url;delete e.url;e=a.typeSystem.extend(e,c)}else e=c;a.service(b,e).then(function(a){return a().onReady().then(function(b){b.serviceFactory= -a;d.deferred.resolve(b,a,a.type)}).fail(function(){d.deferred.reject.apply(d.deferred,arguments)})}).fail(function(){d.deferred.reject.apply(d.deferred,arguments)});return d.getPromise()}})($data); diff --git a/release/jaydatamodules/angular.js b/release/jaydatamodules/angular.js deleted file mode 100644 index d245542a..00000000 --- a/release/jaydatamodules/angular.js +++ /dev/null @@ -1,249 +0,0 @@ -// JayData 1.3.6 -// Dual licensed under MIT and GPL v2 -// Copyright JayStack Technologies (http://jaydata.org/licensing) -// -// JayData is a standards-based, cross-platform Javascript library and a set of -// practices to access and manipulate data from various online and offline sources. -// -// Credits: -// Hajnalka Battancs, Dániel József, János Roden, László Horváth, Péter Nochta -// Péter Zentai, Róbert Bónay, Szabolcs Czinege, Viktor Borza, Viktor Lázár, -// Zoltán Gyebrovszki, Gábor Dolla -// -// More info: http://jaydata.org -(function() { - -Object.defineProperty($data.Entity.prototype, "_isNew", { - get: function () { - return !this.storeToken; - } -}); -Object.defineProperty($data.Entity.prototype, "_isDirty", { - get: function () { - return !this._isNew && this.changedProperties && this.changedProperties.length > 0; - } -}); - -var originalSave = $data.Entity.prototype.save; -var originalRemove = $data.Entity.prototype.remove; -var originalSaveChanges = $data.EntityContext.prototype.saveChanges; - -var _getCacheKey = function (query) { - var key = query.expression.getJSON(); - var hash = 0, i, charC; - if (key.length == 0) return hash; - for (i = 0; i < key.length; i++) { - charC = key.charCodeAt(i); - hash = ((hash << 5) - hash) + charC; - hash = hash & hash; - } - return hash; -} - -angular.module('jaydata', ['ng', ['$provide', function ($provide) { - - $provide.factory('$data', ['$rootScope', '$q', function ($rootScope, $q) { - var cache = {}; - - $data.Entity.prototype.hasOwnProperty = function (propName) { - var member; - if (this.getType && this.getType().memberDefinitions) { - if (member = this.getType().memberDefinitions['$' + propName]) { - return ("property" === member.kind) && member.enumerable; - } else { - return false; - } - } - return Object.prototype.hasOwnProperty.apply(this, arguments); - } - - $data.Queryable.prototype.toLiveArray = function (cb) { - var _this = this; - - var trace = this.toTraceString(); - var cacheKey = _getCacheKey(this); // trace.queryText || trace.sqlText + JSON.stringify(trace.params); - - if (cache[cacheKey]) { - return cache[cacheKey]; - } - - var result = []; - cache[cacheKey] = result; - - result.state = "inprogress"; - result.successHandlers = []; - result.errorHandlers = []; - - - if (cb && typeof cb === 'function') { - chainOrFire(cb, "success"); - } - - function chainOrFire(cb, type) { - if (!cb) return; - var targetCbArr = type === "success" ? result.successHandlers : result.errorHandlers; - if (result.state === "completed") { - cb(result); - } else { - targetCbArr.push(cb); - } - return result; - } - - result.then = result.success = function (cb) { - return chainOrFire(cb, "success"); - }; - - result.error = function (cb) { - return result; - }; - - result.refresh = function (cb) { - //result = []; - result.length = 0; - result.state = "inprogress"; - chainOrFire(cb, "success"); - _this.toArray({ success: result.resolve, error: result.reject }); - return result; - } - - result.resolve = function (items) { - result.state = "completed"; - items.forEach(function (item) { - result.push(item); - }); - result.successHandlers.forEach(function (handler) { - handler(result); - }); - if (!$rootScope.$$phase) $rootScope.$apply(); - } - - result.reject = function (err) { - result.state = "failed"; - result.errorHandlers.forEach(function (handler) { - handler(err); - }); - if (!$rootScope.$$phase) $rootScope.$apply(); - } - - this.toArray({ success: result.resolve, error: result.reject }); - - return result; - }; - - $data.Entity.prototype.save = function () { - var _this = this; - var d = $q.defer(); - originalSave.call(_this).then(function () { - cache = {}; - d.resolve(_this); - if (!$rootScope.$$phase) $rootScope.$apply(); - }).fail(function (err) { - d.reject(err); - if (!$rootScope.$$phase) $rootScope.$apply(); - }); - return d.promise; - }; - - $data.ItemStoreClass.prototype.EntityInstanceSave = function (storeAlias, hint) { - var self = $data.ItemStore; - var entity = this; - return self._getStoreEntitySet(storeAlias, entity) - .then(function (entitySet) { - return self._getSaveMode(entity, entitySet, hint, storeAlias) - .then(function (mode) { - mode = mode || 'add'; - switch (mode) { - case 'add': - entitySet.add(entity); - break; - case 'attach': - entitySet.attach(entity, true); - entity.entityState = $data.EntityState.Modified; - break; - default: - var d = new $data.PromiseHandler(); - var callback = d.createCallback(); - callback.error('save mode not supported: ' + mode); - return d.getPromise(); - } - - return originalSaveChanges.call(entitySet.entityContext) - .then(function () { self._setStoreAlias(entity, entitySet.entityContext.storeToken); return entity; }); - }); - }); - }; - $data.ItemStoreClass.prototype.EntityInstanceRemove = function (storeAlias) { - var self = $data.ItemStore; - var entity = this; - return self._getStoreEntitySet(storeAlias, entity) - .then(function (entitySet) { - entitySet.remove(entity); - - return originalSaveChanges.call(entitySet.entityContext) - .then(function () { return entity; }); - }); - }; - $data.ItemStoreClass.prototype.EntityTypeRemoveAll = function (type) { - return function (storeAlias) { - var self = $data.ItemStore; - return self._getStoreEntitySet(storeAlias, type) - .then(function (entitySet) { - return entitySet.toArray().then(function (items) { - items.forEach(function (item) { - entitySet.remove(item); - }); - - return originalSaveChanges.call(entitySet.entityContext) - .then(function () { return items; }); - }); - }); - } - }; - $data.ItemStoreClass.prototype.EntityTypeAddMany = function (type) { - return function (initDatas, storeAlias) { - var self = $data.ItemStore; - return self._getStoreEntitySet(storeAlias, type) - .then(function (entitySet) { - var items = entitySet.addMany(initDatas); - return originalSaveChanges.call(entitySet.entityContext) - .then(function () { - return items; - }); - }); - } - }; - - $data.Entity.prototype.remove = function () { - var d = $q.defer(); - var _this = this; - originalRemove.call(_this).then(function () { - cache = {}; - d.resolve(_this); - if (!$rootScope.$$phase) $rootScope.$apply(); - }).fail(function (err) { - d.reject(err); - if (!$rootScope.$$phase) $rootScope.$apply(); - }); - - return d.promise; - } - - $data.EntityContext.prototype.saveChanges = function () { - var _this = this; - var d = $q.defer(); - originalSaveChanges.call(_this).then(function (n) { - cache = {}; - d.resolve(n); - if (!$rootScope.$$phase) $rootScope.$apply(); - }).fail(function (err) { - d.reject(err); - if (!$rootScope.$$phase) $rootScope.$apply(); - }); - return d.promise; - } - return $data; - }]); -}]]); - -})(); diff --git a/release/jaydatamodules/angular.min.js b/release/jaydatamodules/angular.min.js deleted file mode 100644 index 387c0b5a..00000000 --- a/release/jaydatamodules/angular.min.js +++ /dev/null @@ -1,21 +0,0 @@ -// JayData 1.3.6 -// Dual licensed under MIT and GPL v2 -// Copyright JayStack Technologies (http://jaydata.org/licensing) -// -// JayData is a standards-based, cross-platform Javascript library and a set of -// practices to access and manipulate data from various online and offline sources. -// -// Credits: -// Hajnalka Battancs, Dániel József, János Roden, László Horváth, Péter Nochta -// Péter Zentai, Róbert Bónay, Szabolcs Czinege, Viktor Borza, Viktor Lázár, -// Zoltán Gyebrovszki, Gábor Dolla -// -// More info: http://jaydata.org -(function(){Object.defineProperty($data.Entity.prototype,"_isNew",{get:function(){return!this.storeToken}});Object.defineProperty($data.Entity.prototype,"_isDirty",{get:function(){return!this._isNew&&this.changedProperties&&0Returns an object of name-value pairs that represents values in a form. - * It is able to nest values whose element's name has square brackets.

- * Example html: - * @codestart html - * <form> - * <input name="foo[bar]" value='2'/> - * <input name="foo[ced]" value='4'/> - * <form/> - * @codeend - * Example code: - * @codestart - * $('form').formBinder() //-> { foo:{bar:2, ced: 4} } - * @codeend - * - * @demo jquery/dom/form_params/form_params.html - * - * @param {Boolean} [convert] True if strings that look like numbers and booleans should be converted. Defaults to true. - * @return {Object} An object of name-value pairs. - */ - formBinder: function (obj, convert) { - if (this[0].nodeName.toLowerCase() == 'form' && this[0].elements) { - - return jQuery(jQuery.makeArray(this[0].elements)).getParams(obj, convert); - } - return jQuery("input[name], textarea[name], select[name]", this[0]).getParams(obj, convert); - }, - getParams: function (obj, convert) { - var data = obj || {}, - current; - - convert = convert === undefined ? true : convert; - - this.each(function () { - var el = this, - type = el.type && el.type.toLowerCase(); - //if we are submit, ignore - if ((type == 'submit') || !el.name) { - return; - } - - var key = el.name, - value = $.data(el, "value") || $.fn.val.call([el]), - isRadioCheck = radioCheck.test(el.type), - parts = key.match(keyBreaker), - write = !isRadioCheck || !!el.checked, - //make an array of values - lastPart; - - if (convert) { - if (isNumber(value)) { - value = parseFloat(value); - } else if (value === 'true' || value === 'false') { - value = Boolean(value); - } - - } - - // go through and create nested objects - current = data; - for (var i = 0; i < parts.length - 1; i++) { - if (!current[parts[i]]) { - current[parts[i]] = {}; - } - current = current[parts[i]]; - } - lastPart = parts[parts.length - 1]; - - //now we are on the last part, set the value - if (lastPart in current && type === "checkbox") { - if (!$.isArray(current[lastPart])) { - current[lastPart] = current[lastPart] === undefined ? [] : [current[lastPart]]; - } - if (write) { - current[lastPart].push(value); - } - } else if (write || !current[lastPart]) { - current[lastPart] = write ? value : undefined; - } - - }); - return data; - } - }); -})(jQuery); \ No newline at end of file diff --git a/release/jaydatamodules/formBinder.min.js b/release/jaydatamodules/formBinder.min.js deleted file mode 100644 index 147004ec..00000000 --- a/release/jaydatamodules/formBinder.min.js +++ /dev/null @@ -1,15 +0,0 @@ -// JayData 1.3.6 -// Dual licensed under MIT and GPL v2 -// Copyright JayStack Technologies (http://jaydata.org/licensing) -// -// JayData is a standards-based, cross-platform Javascript library and a set of -// practices to access and manipulate data from various online and offline sources. -// -// Credits: -// Hajnalka Battancs, Dániel József, János Roden, László Horváth, Péter Nochta -// Péter Zentai, Róbert Bónay, Szabolcs Czinege, Viktor Borza, Viktor Lázár, -// Zoltán Gyebrovszki, Gábor Dolla -// -// More info: http://jaydata.org -(function(d){var j=/radio|checkbox/i,k=/[^\[\]]+/g,l=/^[\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?$/;d.fn.extend({formBinder:function(d,e){return"form"==this[0].nodeName.toLowerCase()&&this[0].elements?jQuery(jQuery.makeArray(this[0].elements)).getParams(d,e):jQuery("input[name], textarea[name], select[name]",this[0]).getParams(d,e)},getParams:function(m,e){var h=m||{},b,e=void 0===e?!0:e;this.each(function(){var i=this.type&&this.type.toLowerCase();if("submit"!=i&&this.name){var a=this.name,c=d.data(this, -"value")||d.fn.val.call([this]),f=j.test(this.type),a=a.match(k),f=!f||!!this.checked;if(e)if("number"==typeof c||("string"!=typeof c?0:c.match(l)))c=parseFloat(c);else if("true"===c||"false"===c)c=Boolean(c);b=h;for(var g=0;ge.references.indexOf(b)&&e.references.push(b)}return{cacheKey:c,clientId:b}}var l=d.Entity.inheritedTypeProcessor,j={templateResolvers:[function(a,b){if(b)return(b=b.trim())?"<"===b[0]||"{"===b[0]?b:void 0:void 0},function(){},function(a,b){if(!b)var c=d.Container.resolveName(a).split("."),b= -c[c.length-1];return $("#"+b).html()}],templateCompiler:function(a){return h.compile(a)},templateCache:{},getTemplate:function(a,b){var c,e,d=a.fullName+"::"+b;e=c=this.templateCache[d];for(i=0;!c&&iarguments.length&&(a=void 0);return new h.SafeString(d.render(this,a))});d.displayCache={};var n=0,m=0;h.registerHelper("entityScope",function(){var a=d.Container.resolveName(this.getType()).split("."), -a=a[a.length-1],b=this[this.getType().memberDefinitions.getKeyProperties()[0].name],a="data-"+a.toLowerCase()+"-"+b,b=k(this),a=a+(" data-cache-client="+b.clientId);return a+=" data-cache-item="+b.cacheKey});h.registerHelper("entityCommand",function(a){d.entityCache=d.entityCache||{};var b=d.Container.resolveName(this.getType()).split("."),b=b[b.length-1],c=this[this.getType().memberDefinitions.getKeyProperties()[0].name],e=b+":"+c;d.entityCache[e]||(d.entityCache[e]=this);a="data-command="+a+" data-type="+ -b+" data-id="+c;b=k(this);a+=" data-cache-client="+b.clientId;return a+=" data-cache-item="+b.cacheKey});d.setCommandHandler=function(a,b){$(b||document).delegate("[data-command]","click",function(){$(this).data("type");$(this).data("id");var b=a[$(this).data("command")+$(this).data("type")],e=$(this).data("cache-item"),e=[d.displayCache[e].value,$(this).data("id")];b.apply(a,e)})};$(document).delegate(".single-select","click",function(a){a=$(a.srcElement).parentsUntil(this);$(this).children().removeClass("active"); -a.addClass("active")})})($data,Handlebars); diff --git a/release/jaydatamodules/inMemory.js b/release/jaydatamodules/inMemory.js deleted file mode 100644 index 641a8879..00000000 --- a/release/jaydatamodules/inMemory.js +++ /dev/null @@ -1,45 +0,0 @@ -// JayData 1.3.6 -// Dual licensed under MIT and GPL v2 -// Copyright JayStack Technologies (http://jaydata.org/licensing) -// -// JayData is a standards-based, cross-platform Javascript library and a set of -// practices to access and manipulate data from various online and offline sources. -// -// Credits: -// Hajnalka Battancs, Dániel József, János Roden, László Horváth, Péter Nochta -// Péter Zentai, Róbert Bónay, Szabolcs Czinege, Viktor Borza, Viktor Lázár, -// Zoltán Gyebrovszki, Gábor Dolla -// -// More info: http://jaydata.org -(function ($data) { - - $data.Array.prototype.toQueryable = function () { - if (this.length > 0) { - var firtsItem = this[0]; - var type = Container.resolveType(Container.getTypeName(firtsItem)); - - if (!type.isAssignableTo || !type.isAssignableTo($data.Entity)) - Guard.raise(new Exception("Type '" + Container.resolveName(type) + "' is not subclass of $data.Entity", "Not supported", type)); - - for (var i = 0; i < this.length; i++) { - Guard.requireType('array item check', this[i], type); - } - - } - - var typeName = 'inMemoryArray_' + type.name; - if (!Container.isTypeRegistered(typeName)) { - $data.EntityContext.extend(typeName, { - Source: { - type: $data.EntitySet, - elementType: type - } - }); - } - - var context = Container['create' + typeName]({ name: 'InMemory', source: { Source: this} }); - - return context.Source; - } - -})($data); \ No newline at end of file diff --git a/release/jaydatamodules/inMemory.min.js b/release/jaydatamodules/inMemory.min.js deleted file mode 100644 index 4607c585..00000000 --- a/release/jaydatamodules/inMemory.min.js +++ /dev/null @@ -1,15 +0,0 @@ -// JayData 1.3.6 -// Dual licensed under MIT and GPL v2 -// Copyright JayStack Technologies (http://jaydata.org/licensing) -// -// JayData is a standards-based, cross-platform Javascript library and a set of -// practices to access and manipulate data from various online and offline sources. -// -// Credits: -// Hajnalka Battancs, Dániel József, János Roden, László Horváth, Péter Nochta -// Péter Zentai, Róbert Bónay, Szabolcs Czinege, Viktor Borza, Viktor Lázár, -// Zoltán Gyebrovszki, Gábor Dolla -// -// More info: http://jaydata.org -(function(c){c.Array.prototype.toQueryable=function(){if(0= 200 && statusCode <= 299) { - success(event.data); - } else { - error(event.data); - } - }; - window.addEventListener('message', listener, false); - $data.Trace.log('before post', targetIframe); - targetIframe.postMessage(request, targetOrigin); - } else { - return odata.originalHttpClient.request(request, success, error); - } - } - }, - requestProxy: function (request, success, error) { - success = request.success || success; - error = request.error || error; - - delete request.success; - delete request.error; - - var targetIframe = request.targetIframe || $data.postMessageODataHandler.postMessageHttpClient.targetIframe; - var targetOrigin = request.targetOrigin || $data.postMessageODataHandler.postMessageHttpClient.targetOrigin || '*'; - - - if (targetIframe) { - request.requestProxy = true; - var listener = function (event) { - $data.Trace.log('in listener'); - window.removeEventListener('message', listener); - var statusCode = event.data.statusCode; - if (statusCode >= 200 && statusCode <= 299) { - success(event.data); - } else { - error(event.data); - } - }; - window.addEventListener('message', listener, false); - $data.Trace.log('before post', targetIframe); - targetIframe.postMessage(request, targetOrigin); - } else { - error({ message: "No iframe detected", request: request, response: undefined }); - } - } - }; - odata.defaultHttpClient = $data.postMessageODataHandler.postMessageHttpClient; - -})($data, window); - -(function ($data) { - $data.MsCrm = { - disableBatch: true - }; - $data.MsCrm.Auth = { - trace: true, - clientAuthorizationPath: "/WebResources/new_authorize.html", - messageHandlerPath: "/WebResources/new_postmessage.html", - login: function do_login(crmUrl, cb, local) { - var iframe; - - var onMessagehandlerLoaded = function (e) { - if ($data.MsCrm.Auth.trace) $data.Trace.log("Message received", crmUrl); - if (e.data.MessageHandlerLoaded) { - if ($data.MsCrm.Auth.trace) $data.Trace.log("Message handler loaded", crmUrl); - window.removeEventListener("message", onMessagehandlerLoaded); - window.OData.defaultHttpClient.targetIframe = iframe.contentWindow; - cb(iframe.contentWindow, crmUrl); - } - } - - var onAuthenticated = function (e) { - iframe = document.createElement("iframe"); - if (e.data.Authenticated) { - $data.Trace.log("Logged in to CRM: " + crmUrl); - window.removeEventListener("message", onAuthenticated); - window.addEventListener("message", onMessagehandlerLoaded); - var url = local ? "postmessage.html" : crmUrl + $data.MsCrm.Auth.messageHandlerPath; - iframe.src = url; - iframe.style.display = "none"; - document.body.appendChild(iframe); - } - } - window.addEventListener("message", onAuthenticated); - var url = local ? "authorize.html" : crmUrl + $data.MsCrm.Auth.clientAuthorizationPath; - url = url; - var w = window.open(url, "_blank", "resizable=false,location=0,menubar=0,toolbar=0,width=400,height=600"); - } - - } - $data.MsCrm.init = function (crmAddress, contextType, cb) { - var config = {}; - if (typeof crmAddress === 'object' && crmAddress) { - config = crmAddress; - crmAddress = config.url; - delete config.url; - } - var serviceUrl = crmAddress + '/XRMServices/2011/OrganizationData.svc'; - - if (window.location.href.indexOf(crmAddress) > -1) { - initContext(); - } else { - $data.MsCrm.Auth.login(crmAddress, function () { - initContext(); - }); - } - - function initContext() { - if (!(contextType.isAssignableTo && contextType.isAssignableTo($data.EntityContext))) { - cb = contextType; - config.disableBatch = $data.MsCrm.disableBatch; - $data.service(serviceUrl, config, function (factory) { - var ctx = factory(); - ctx.onReady().then(function () { - cb(ctx, factory); - }); - }); - } else { - function factory() { - return new contextType({ name: 'oData', oDataServiceHost: serviceUrl, disableBatch: $data.MsCrm.disableBatch }); - } - var ctx = factory(); - ctx.onReady().then(function () { - cb(ctx, factory); - }); - } - } - } - -})($data); \ No newline at end of file diff --git a/release/jaydatamodules/jaydata.mscrm.min.js b/release/jaydatamodules/jaydata.mscrm.min.js deleted file mode 100644 index e88c4dce..00000000 --- a/release/jaydatamodules/jaydata.mscrm.min.js +++ /dev/null @@ -1,19 +0,0 @@ -// JayData 1.3.6 -// Dual licensed under MIT and GPL v2 -// Copyright JayStack Technologies (http://jaydata.org/licensing) -// -// JayData is a standards-based, cross-platform Javascript library and a set of -// practices to access and manipulate data from various online and offline sources. -// -// Credits: -// Hajnalka Battancs, Dániel József, János Roden, László Horváth, Péter Nochta -// Péter Zentai, Róbert Bónay, Szabolcs Czinege, Viktor Borza, Viktor Lázár, -// Zoltán Gyebrovszki, Gábor Dolla -// -// More info: http://jaydata.org -(function(b,c,h){var f=c.OData;f.originalHttpClient=f.defaultHttpClient;b.postMessageODataHandler={postMessageHttpClient:{targetIframe:h,request:function(a,e,g){var d=a.targetIframe||b.postMessageODataHandler.postMessageHttpClient.targetIframe,h=a.targetOrigin||b.postMessageODataHandler.postMessageHttpClient.targetOrigin||"*";if(d){var i=function(a){b.Trace.log("in listener");c.removeEventListener("message",i);var d=a.data.statusCode;200<=d&&299>=d?e(a.data):g(a.data)};c.addEventListener("message", -i,!1);b.Trace.log("before post",d);d.postMessage(a,h)}else return f.originalHttpClient.request(a,e,g)}},requestProxy:function(a,e,g){e=a.success||e;g=a.error||g;delete a.success;delete a.error;var d=a.targetIframe||b.postMessageODataHandler.postMessageHttpClient.targetIframe,f=a.targetOrigin||b.postMessageODataHandler.postMessageHttpClient.targetOrigin||"*";if(d){a.requestProxy=!0;var i=function(a){b.Trace.log("in listener");c.removeEventListener("message",i);var d=a.data.statusCode;200<=d&&299>= -d?e(a.data):g(a.data)};c.addEventListener("message",i,!1);b.Trace.log("before post",d);d.postMessage(a,f)}else g({message:"No iframe detected",request:a,response:h})}};f.defaultHttpClient=b.postMessageODataHandler.postMessageHttpClient})($data,window); -(function(b){b.MsCrm={disableBatch:!0};b.MsCrm.Auth={trace:!0,clientAuthorizationPath:"/WebResources/new_authorize.html",messageHandlerPath:"/WebResources/new_postmessage.html",login:function(c,h,f){var a,e=function(d){b.MsCrm.Auth.trace&&b.Trace.log("Message received",c);d.data.MessageHandlerLoaded&&(b.MsCrm.Auth.trace&&b.Trace.log("Message handler loaded",c),window.removeEventListener("message",e),window.OData.defaultHttpClient.targetIframe=a.contentWindow,h(a.contentWindow,c))},g=function(d){a= -document.createElement("iframe");d.data.Authenticated&&(b.Trace.log("Logged in to CRM: "+c),window.removeEventListener("message",g),window.addEventListener("message",e),a.src=f?"postmessage.html":c+b.MsCrm.Auth.messageHandlerPath,a.style.display="none",document.body.appendChild(a))};window.addEventListener("message",g);window.open(f?"authorize.html":c+b.MsCrm.Auth.clientAuthorizationPath,"_blank","resizable=false,location=0,menubar=0,toolbar=0,width=400,height=600")}};b.MsCrm.init=function(c,h,f){function a(){if(!h.isAssignableTo|| -!h.isAssignableTo(b.EntityContext))f=h,e.disableBatch=b.MsCrm.disableBatch,b.service(g,e,function(a){var b=a();b.onReady().then(function(){f(b,a)})});else{var a=function(){return new h({name:"oData",oDataServiceHost:g,disableBatch:b.MsCrm.disableBatch})},c=a();c.onReady().then(function(){f(c,a)})}}var e={};"object"===typeof c&&c&&(e=c,c=e.url,delete e.url);var g=c+"/XRMServices/2011/OrganizationData.svc";-1Contains options.owningContextType if initialized in a scope of a context - var memberDefinitions = type.memberDefinitions, - fields = {}; - //debugger; - function getNullable(canonicType, pd) { - if (canonicType === "$data.Boolean") { - //grid validation errs on requied/nonnull bools - return true; - } - return pd.required !== true; - }; - - function getRequired(canonicType, pd) { - if ("$data.Boolean" === canonicType) { - return false; - } - return pd.required || "nullable" in pd ? !(pd.nullable) : false; - } - - memberDefinitions - .getPublicMappedProperties() - .forEach(function (pd) { - var canonicType = $data.Container.resolveName(pd.type); - //if (pd.dataType !== "Array" && !(pd.inverseProperty)) { - fields[pd.name] = { - //TODO - type: getKendoTypeName(canonicType, pd), - nullable: getNullable(canonicType, pd), - defaultValue: pd.defaultValue, - //nullable: false, - //nullable: "nullable" in pd ? pd.nullable : true, - editable: !pd.computed, - //defaultValue: true, - //defaultValue: 'abc', - //defaultValue: pd.type === "Edm.Boolean" ? false : undefined, - validation: { - required: getRequired(canonicType, pd) - } - } - //}; - }); - - function setInitialValue(obj, memDef) { - return; - //if (!obj[memDef.name]) { - // function getDefault() { - // switch ($data.Container.resolveType(memDef.type)) { - // case $data.Number: return 0.0; - // case $data.Integer: return 0; - // case $data.Date: return new Date(); - // case $data.Boolean: return false; - // } - // } - // obj[memDef.name] = getDefault(); - //} - } - - //console.dir(memberDefinitions.getPublicMappedMethods()); - var modelDefinition = { - fields: fields, - init: function (data) { - //console.dir(arguments); - var ctxType = options && options.owningContextType || undefined; - - var contextSetTypes = []; - if (options && options.owningContextType) { - contextSetTypes = options.owningContextType - .memberDefinitions - .getPublicMappedProperties() - .filter(function (pd) { - return $data.Container.resolveType(pd.type) === $data.EntitySet - }) - .map(function (pd) { - return $data.Container.resolveType(pd.elementType) - }); - } - - var newInstanceOptions = { - entityBuilder: function (instance, members) { - members.forEach(function (memberInfo) { - if (!(memberInfo.key === true) && (memberInfo.required === true || memberInfo.nullable === false)) { - var memberType = $data.Container.resolveType(memberInfo.type); - if (memberType.isAssignableTo && memberType.isAssignableTo($data.Entity) && contextSetTypes.indexOf(memberType) === -1) { - //it's a complex property - var _data; - if (data) { - _data = data[memberInfo.name]; - } - instance[memberInfo.name] = new memberType(_data, newInstanceOptions); - } - else { - setInitialValue(instance, memberInfo); - } - } - }); - } - } - - var jayInstance = data instanceof type ? data : new type(data, newInstanceOptions); - - var seed = jayInstance.initData; - - var feed = {}; - - //TODO create precompiled strategy - for (var j in seed) { - var md = type.getMemberDefinition(j); - var seedValue = seed[j]; - if (seedValue instanceof $data.Entity) { - var kendoInstance = seedValue.asKendoObservable(); - feed[j] = kendoInstance; - } - else if (md && $data.Container.resolveType(md.type) === Array) { - var jayType = $data.Container.resolveType(md.elementType); - var kendoType = jayType; - if (jayType.asKendoModel) { - kendoType = jayType.asKendoModel(); - } - var feedValue = new kendo.data.ObservableArray(seed[j], kendoType); - feed[j] = feedValue; - feed[j].bind('change', function (e) { - jayInstance.changeFromKendo = true; - this.parent().dirty = true; - jayInstance[md.name] = this.toJSON(); - delete jayInstance.changeFromKendo; - }); - } - else if (md && $data.Container.resolveType(md.type) === $data.Blob){ - feed[j] = $data.Blob.toBase64(seedValue); - //feed[j] = new kendo.data.Observable($data.Blob.toBase64(seedValue)); - /*feed[j].bind('change', function(e){ - //jayInstance.changeFromKendo = true; - jayInstance[md.name] = $data.Container.convertTo(atob(this), $data.Blob); - //delete jayInstance.changeFromKendo; - });*/ - } - else { - feed[j] = seedValue; - } - } - - var arrayMemberDef = type.memberDefinitions.getPublicMappedProperties().filter(function (item) { - return (($data.Container.resolveType(item.dataType) === Array) && (!$data.Container.resolveType(item.elementType).asKendoModel)) - }); - for (var j = 0; j < arrayMemberDef.length; j++) { - var memberDef = arrayMemberDef[j]; - if (seed[memberDef.name] === null || seed[memberDef.name] === undefined) { - feed[memberDef.name] = new kendo.data.ObservableArray([], $data.Container.resolveType(memberDef.elementType)) - feed[memberDef.name].bind('change', function (e) { - jayInstance.changeFromKendo = true; - this.parent().dirty = true; - jayInstance[memberDef.name] = this.toJSON(); - delete jayInstance.changeFromKendo; - }); - } - } - - var self = this; - this.innerInstance = function () { - return jayInstance - } - - //kendo.data.Model.fn.init.call(this, feed); - $data.kendo.BaseModelType.fn.init.call(this, feed); - - jayInstance.propertyChanged.attach(function (obj, propinfo) { - var jay = this; - var newValue = propinfo.newValue; - var md = jayInstance.getType().getMemberDefinition(propinfo.propertyName); - if (!jay.changeFromKendo) { - newValue = newValue ? (newValue.asKendoObservable ? newValue.asKendoObservable() : newValue) : newValue; - jayInstance.changeFromJay = true; - if ($data.Container.resolveType(md.type) === $data.Blob && newValue){ - newValue = $data.Blob.toBase64(newValue); - } - self.set(propinfo.propertyName, newValue); - if (md.computed && self[propinfo.propertyName] !== newValue){ - self[propinfo.propertyName] = newValue; - } - delete jayInstance.changeFromJay; - }else{ - if ($data.Container.resolveType(md.type) === $data.Blob){ - var blob = $data.Blob.toString(newValue); - newValue = $data.Container.convertTo(atob(blob), $data.Blob); - jayInstance.changeFromJay = true; - jayInstance.initData[md.name] = newValue; - //self.set(propinfo.propertyName, blob); - delete jayInstance.changeFromJay; - } - } - }); - - this.bind("set", function (e) { - var propName = e.field; - var propNameParts = propName.split("."); - jayInstance.changeFromKendo = true; - if (propNameParts.length == 1) { - var propValue = e.value; - if (!jayInstance.changeFromJay) { - propValue = propValue.innerInstance ? propValue.innerInstance() : propValue; - jayInstance[propName] = propValue; - if (options && options.autoSave) { - jayInstance.save(); - } - } - } - else { - var rootProp = jayInstance[propNameParts[0]]; - if (rootProp instanceof $data.Entity) { - jayInstance[propNameParts[0]] = rootProp; - } - } - delete jayInstance.changeFromKendo; - }); - if (options && options.newInstanceCallback) { - options.newInstanceCallback(jayInstance); - } - }, - save: function () { - //console.log("item.save", this, arguments); - return this.innerInstance().save(); - }, - remove: function () { - return this.innerInstance().remove(); - } - - }; - - var keyProperties = memberDefinitions.getKeyProperties(); - switch (keyProperties.length) { - case 0: - break; - case 1: - modelDefinition.id = keyProperties[0].name; - break; - default: - console.warn("entity with multiple keys not supported"); - break; - } - $data.Trace.log("md", modelDefinition); - - var returnValue = kendo.data.Model.define($data.kendo.BaseModelType, modelDefinition); - - return returnValue; - } - - function asKendoModel(options) { - var cacheObject = options || type; - return cacheObject.kendoModelType || (cacheObject.kendoModelType = createKendoModel(options)); - } - - function asKendoObservable(instance, options) { - var kendoModel = type.asKendoModel(options); - return new kendoModel(instance); - } - - type.asKendoModel = asKendoModel; - //type.asKendoModelType = asKendoModel; - - type.prototype.asKendoObservable = function (options) { - var self = this; - - var kendoObservable = asKendoObservable(this, options); - - return kendoObservable; - } - - function r(value) { - return value || ''; - } - function registerStoreAlias(type, options) { - if (!options.provider) - return; - var key = r(options.databaseName) + r(options.tableName) + r(options.url) + r(options.apiUrl) + r(options.oDataServiceHost); - var storeDef = { - provider: options.provider, - databaseName: options.databaseName, - tableName: options.tableName, - dataSource: options.url, - apiUrl: options.apiUrl, - oDataServiceHost: options.oDataServiceHost - }; - Object.keys(storeDef).forEach(function (k) { - delete options[k]; - }); - - type.setStore(key, storeDef); - return key; - } - - type.asKendoDataSource = function (options, modelOptions, storeAlias) { - options = options || {}; - var mOptions = modelOptions || {}; - var salias = registerStoreAlias(type, options) || storeAlias; - var token = $data.ItemStore._getStoreAlias(type, salias); - var ctx = $data.ItemStore._getContextPromise(token, type); - var set = ctx.getEntitySetFromElementType(type); - return set.asKendoDataSource(options, mOptions); - }; - - if (oldProcessor) { - oldProcessor(type); - } - } - $data.Queryable.addMember("asKendoColumns", function (columns) { - var result = []; - columns = columns || {}; - var showComplex = columns['$showComplexFields'] === true; - delete columns['$showComplexFields']; - - this.defaultType - .memberDefinitions - .getPublicMappedProperties() - .forEach(function (pd) { - //if (pd.dataType !== "Array" && !(pd.inverseProperty)) { - if (showComplex || kendoTypeMap[$data.Container.resolveName(pd.type)]) { - var col = columns[pd.name] || {}; - var colD = { field: pd.name }; - $.extend(colD, col) - result.push(colD); - } - //} - }); - - function append(field) { - field = Array.isArray(field) ? field : [field]; - var result = this.concat(field); - return prepareResult(result); - } - - function prepend(field) { - field = Array.isArray(field) ? field : [field]; - var result = field.concat(this); - return prepareResult(result); - } - - function setColumn(colName, def) { - var it = this.filter(function (item) { - return item.field == colName - })[0]; - $.extend(it, def); - return this; - } - - function prepareResult(r) { - r.prepend = prepend; - r.append = append; - r.setColumn = setColumn; - return r; - } - return prepareResult(result); - //return ['id', 'Year', 'Manufacturer', { command: ["edit", "create", "destroy", "update"] }]; - }), - - //, { command: ["edit", "create", "destroy", "update"]} - $data.EntityContext.addProperty("EntitySetNames", function () { - var self = this; - //var sets = Object.keys(self._entitySetReferences); - //return sets; - return Object.keys(self._entitySetReferences).map(function (set) { - return self._entitySetReferences[set].tableName; - }); - }); - - $data.Queryable.addMember("asKendoModel", function (options) { - options.owningContextType = options.owningContextType || this.entityContext.getType(); - return this.defaultType.asKendoModel(options); - }); - - $data.Queryable.addMember("asKendoRemoteTransportClass", function (modelItemClass) { - var self = this; - var ctx = self.entityContext; - function reset() { - ctx.stateManager.reset(); - }; - var TransportClass = kendo.data.RemoteTransport.extend({ - init: function () { - this.items = []; - }, - read: function (options) { - var query = self; - - query.entityContext.onReady().then(function () { - var _this = this; - var q = query; - var sp = query.entityContext.storageProvider; - var withInlineCount = query.entityContext.storageProvider.supportedSetOperations.withInlineCount; - var withLength = (!withInlineCount) && query.entityContext.storageProvider.supportedSetOperations.length; - - if (withInlineCount) { - q = q.withInlineCount(); - } - - if (options.data.filter) { - var filter = ""; - var thisArg = {}; - options.data.filter.filters.forEach(function (f, index) { - if (index > 0) { - filter += options.data.filter.logic == "or" ? " || " : " && "; - } - - switch (f.operator) { - case 'eq': - filter += "it." + f.field; - filter += " == this." + f.field; - break; - case 'neq': - filter += "it." + f.field; - filter += " != this." + f.field; - break; - case 'startswith': - filter += "it." + f.field; - filter += ".startsWith(this." + f.field + ")"; - break; - case 'contains': - filter += "it." + f.field; - filter += ".contains(this." + f.field + ")"; - break; - case 'doesnotcontain': - filter += "!"; - filter += "it." + f.field; - filter += ".contains(this." + f.field + ")"; - break; - case 'endswith': - filter += "it." + f.field; - filter += ".endsWith(this." + f.field + ")"; - break; - case 'gte': - filter += "it." + f.field; - filter += " >= this." + f.field; - break; - case 'gt': - filter += "it." + f.field; - filter += " > this." + f.field; - break; - case 'lte': - filter += "it." + f.field; - filter += " <= this." + f.field; - break; - case 'lt': - filter += "it." + f.field; - filter += " < this." + f.field; - break; - default: - $data.Trace.log('unknown operator', f.operator); - break; - } - thisArg[f.field] = f.value; - }) - q = q.filter(filter, thisArg); - } - var allItemsQ = q; - - if (options.data.sort) { - options.data.sort.forEach(function (s) { - q = q.order((s.dir == 'desc' ? "-" : "") + s.field); - }) - } - - if (options.data.skip) { - q = q.skip(options.data.skip); - } - if (options.data.take) { - q = q.take(options.data.take); - } - - //Data.defaultHttpClient.enableJsonpCallback = true; - var promises = []; - - promises.push(q.toArray()); - //var ta = q.toArray(); - if (withLength) { - promises.push(allItemsQ.length()); - } - else if (!withInlineCount) { - promises.push(allItemsQ.toArray()); - } - - $data.Trace.log(promises); - jQuery.when.apply(this, promises).then(function (items, total) { - console.dir(arguments); - //var result = items.map(function (item) { return item instanceof $data.Entity ? new model(item.initData) : item; }); - var result = items.map(function (item) { - var d = (item instanceof $data.Entity) ? item.initData : item; - var kendoItem = item.asKendoObservable(); - return kendoItem; - }); - var r = { - data: result, - total: withInlineCount ? items.totalCount : (withLength ? total : total.length) - } - $data.Trace.log(r); - options.success(r); - }).fail(function () { - console.log("error in create"); - options.error({}, arguments); - }); - }); - }, - create: function (options, model) { - var query = self; - query.entityContext.onReady().then(function () { - if (model.length > 1) { - var modelItems = []; - model.forEach(function (modelItem) { - modelItems.push(modelItem.innerInstance()); - }); - ctx.addMany(modelItems); - ctx.saveChanges().then(function () { - var data = []; - modelItems.forEach(function (modelItem) { - data.push(modelItem.initData); - }); - options.success(/*{ data: data }*/); - }).fail(function () { - console.log("error in create"); - options.error({}, arguments); - ctx.stateManager.reset(); - }); - } - else { - console.dir(ctx.storeToken); - model[0] - .innerInstance() - .save(ctx.storeToken) - .then(function () { - options.success(/*{ data: model[0].innerInstance().initData }*/); - }) - .fail(function () { - console.log("error in create"); - options.error({}, arguments); - }); - } - }); - }, - update: function (options, model) { - var query = self; - query.entityContext.onReady().then(function () { - if (model.length > 1) { - var items = model.map(function (item) { - return item.innerInstance() - }); - items.forEach(function (item) { - ctx.attach(item, true); - }); - ctx.saveChanges().then(function () { - options.success(); - }).fail(function () { - ctx.stateManager.reset(); - //alert("error in batch update"); - options.error({}, arguments); - }); - } - else { - model[0].innerInstance().save().then(function (item) { - options.success(); - }).fail(function () { - //alert("error in update") - options.error({}, arguments); - }); - } - }); - }, - - destroy: function (options, model) { - var query = self; - query.entityContext.onReady().then(function () { - if (model.length > 1) { - model.forEach(function (item) { - ctx.remove(item.innerInstance()); - }); - ctx.saveChanges().then(function () { - options.success({ data: options.data }); - }).fail(function () { - ctx.stateManager.reset(); - //alert("error in save:" + arguments[0]); - options.error({}, "error", options.data); - }); - } - else { - model[0].innerInstance().remove().then(function () { - options.success({ data: options.data }); - }).fail(function () { - ctx.stateManager.reset(); - //alert("error in save:" + arguments[0]); - options.error({}, "error", options.data); - }); - } - }); - }, - setup: function () { - $data.Trace.log("setup"); - $data.Trace.log(arguments); - } - }); - return TransportClass; - }); - - var jayDataSource = kendo.data.DataSource.extend({ - init: function () { - kendo.data.DataSource.fn.init.apply(this, arguments); - }, - createItem: function (initData) { - var type = this.options.schema.model; - return new type(initData); - }, - _promise: function (data, models, type) { - var that = this, - extend = $.extend, - transport = that.transport; - - return $.Deferred(function (deferred) { - transport[type].call(transport, extend({ - success: function (response) { - deferred.resolve({ - response: response, - models: models, - type: type - }); - }, - error: function (response, status, error) { - deferred.reject(response); - that.error(response, status, error); - } - }, data), models - ); - }).promise(); - } - }); - - $data.kendo = $data.kendo || {}; - - $data.kendo.defaultPageSize = 25; - - $data.Queryable.addMember("asKendoDataSource", function (ds, modelOptions) { - var self = this; - - modelOptions = modelOptions || {}; - var model = self.asKendoModel(modelOptions); - - ds = ds || {}; - //unless user explicitly opts out server side logic - //we just force it. - ds.serverPaging = ds.serverPaging || true; - ds.serverFiltering = ds.serverFiltering || true; - ds.serverSorting = ds.serverSorting || true; - ds.pageSize = ds.pageSize === undefined ? $data.kendo.defaultPageSize : ds.pageSize; - - var TransportClass = self.asKendoRemoteTransportClass(model); - ds.transport = new TransportClass(); - - ds.schema = { - model: model, - data: "data", - total: "total" - }; - return new jayDataSource(ds); - }); - - kendo.data.binders.submit = kendo.data.Binder.extend({ - init: function (element, bindings, options) { - kendo.data.Binder.fn.init.call(this, element, bindings, options); - $(element).bind("submit", function () { - var obj = bindings.submit.source; - var fn = obj[bindings.submit.path]; - if (typeof fn === 'function') { - fn.apply(obj, arguments); - return false; - } - }); - }, - refresh: function () { - } - }); -})($data); \ No newline at end of file diff --git a/release/jaydatamodules/kendo.min.js b/release/jaydatamodules/kendo.min.js deleted file mode 100644 index f8470174..00000000 --- a/release/jaydatamodules/kendo.min.js +++ /dev/null @@ -1,32 +0,0 @@ -// JayData 1.3.6 -// Dual licensed under MIT and GPL v2 -// Copyright JayStack Technologies (http://jaydata.org/licensing) -// -// JayData is a standards-based, cross-platform Javascript library and a set of -// practices to access and manipulate data from various online and offline sources. -// -// Credits: -// Hajnalka Battancs, Dániel József, János Roden, László Horváth, Péter Nochta -// Péter Zentai, Róbert Bónay, Szabolcs Czinege, Viktor Borza, Viktor Lázár, -// Zoltán Gyebrovszki, Gábor Dolla -// -// More info: http://jaydata.org -(function(d){var l=d.Entity.inheritedTypeProcessor;d.kendo={};d.kendo.BaseModelType=kendo.data.Model.define({init:function(a){kendo.data.Model.fn.init.call(this,a)}});var q={"$data.Blob":"string","$data.String":"string","$data.Boolean":"boolean","$data.Integer":"number","$data.Number":"number","$data.Date":"date","$data.DateTimeOffset":"date","$data.Time":"string","$data.Byte":"number","$data.SByte":"number","$data.Int16":"number","$data.Int32":"number","$data.Int64":"number","$data.Decimal":"string", -"$data.Float":"number"};d.Entity.inheritedTypeProcessor=function(a){function f(b){var e=a.memberDefinitions,h={};e.getPublicMappedProperties().forEach(function(a){var c=d.Container.resolveName(a.type);h[a.name]={type:q[c]||"object",nullable:"$data.Boolean"===c?!0:!0!==a.required,defaultValue:a.defaultValue,editable:!a.computed,validation:{required:"$data.Boolean"===c?!1:a.required||"nullable"in a?!a.nullable:!1}}});var c={fields:h,init:function(c){var e=[];b&&b.owningContextType&&(e=b.owningContextType.memberDefinitions.getPublicMappedProperties().filter(function(a){return d.Container.resolveType(a.type)=== -d.EntitySet}).map(function(a){return d.Container.resolveType(a.elementType)}));var h={entityBuilder:function(a,g){g.forEach(function(g){if(!0!==g.key&&(!0===g.required||!1===g.nullable)){var b=d.Container.resolveType(g.type);if(b.isAssignableTo&&b.isAssignableTo(d.Entity)&&-1===e.indexOf(b)){var f;c&&(f=c[g.name]);a[g.name]=new b(f,h)}}})}},g=c instanceof a?c:new a(c,h),f=g.initData,j={},k;for(k in f){var m=a.getMemberDefinition(k),i=f[k];if(i instanceof d.Entity)i=i.asKendoObservable(),j[k]=i;else if(m&& -d.Container.resolveType(m.type)===Array){var l=i=d.Container.resolveType(m.elementType);i.asKendoModel&&(l=i.asKendoModel());i=new kendo.data.ObservableArray(f[k],l);j[k]=i;j[k].bind("change",function(){g.changeFromKendo=!0;this.parent().dirty=!0;g[m.name]=this.toJSON();delete g.changeFromKendo})}else j[k]=m&&d.Container.resolveType(m.type)===d.Blob?d.Blob.toBase64(i):i}i=a.memberDefinitions.getPublicMappedProperties().filter(function(a){return d.Container.resolveType(a.dataType)===Array&&!d.Container.resolveType(a.elementType).asKendoModel}); -for(k=0;k', - iElems[0] - ){}; - return version > 4 ? version : undefined; - }()); - - ko.utils.ensureSelectElementIsRenderedCorrectly = function(selectElement) { - // Workaround for IE9 rendering bug - it doesn't reliably display all the text in dynamically-added select boxes unless you force it to re-render by updating the width. - // (See https://github.com/SteveSanderson/knockout/issues/312, http://stackoverflow.com/questions/5908494/select-only-shows-first-char-of-selected-option) - if (ieVersion >= 9) { - var originalWidth = selectElement.style.width; - selectElement.style.width = 0; - selectElement.style.width = originalWidth; - } - }; - - ko.utils.setOptionNodeSelectionState = function (optionNode, isSelected) { - // IE6 sometimes throws "unknown error" if you try to write to .selected directly, whereas Firefox struggles with setAttribute. Pick one based on browser. - if (navigator.userAgent.indexOf("MSIE 6") >= 0) - optionNode.setAttribute("selected", isSelected); - else - optionNode.selected = isSelected; - }; - - ko.utils.setTextContent = function(element, textContent) { - var value = ko.utils.unwrapObservable(textContent); - if ((value === null) || (value === undefined)) - value = ""; - - 'innerText' in element ? element.innerText = value - : element.textContent = value; - - if (ieVersion >= 9) { - // Believe it or not, this actually fixes an IE9 rendering bug - // (See https://github.com/SteveSanderson/knockout/issues/209) - element.style.display = element.style.display; - } - }; - - function ensureDropdownSelectionIsConsistentWithModelValue(element, modelValue, preferModelValue) { - if (preferModelValue) { - if (modelValue !== ko.selectExtensions.readValue(element)) - ko.selectExtensions.writeValue(element, modelValue); - } - - // No matter which direction we're syncing in, we want the end result to be equality between dropdown value and model value. - // If they aren't equal, either we prefer the dropdown value, or the model value couldn't be represented, so either way, - // change the model value to match the dropdown. - if (modelValue !== ko.selectExtensions.readValue(element)) - ko.utils.triggerEvent(element, "change"); - }; - - ko.bindingHandlers['options'] = { - 'update': function (element, valueAccessor, allBindingsAccessor) { - if (element.tagName.toLowerCase() !== "select") - throw new Error("options binding applies only to SELECT elements"); - - var selectWasPreviouslyEmpty = element.length == 0; - var previousSelectedValues = ko.utils.arrayMap(ko.utils.arrayFilter(element.childNodes, function (node) { - return node.tagName && (node.tagName.toLowerCase() === "option") && node.selected; - }), function (node) { - return ko.selectExtensions.readValue(node) || node.innerText || node.textContent; - }); - var previousScrollTop = element.scrollTop; - - var value = ko.utils.unwrapObservable(valueAccessor()); - var selectedValue = element.value; - - // Remove all existing