Alright everyone, I have finished the xJSON object suite, or at least a decent first pass. This was a bigger project than I expected and I apologize for dragging it out over the past couple weeks. It seemed like every time I was about to finish, I would uncover a corner case that would break an entire second of the project. Anyway, I was away over the passed weekend and had to do a lot work in the evening last week, and missed your Tuesday post as well. I hope to be better about getting two articles written a week. I am also open to guest posts, if you are interest just leave a comment on any article.
Anyway, I have written the following objects: JsonObject, JsonArray, XJsonObject, and XJsonArray. Here they are:
/** * The JsonObject class manages a JSON object by creating getter and setters * @namespace Core.Model * @class JsonObject * @dependencies library */ Core.Model.JsonObject = function(json) { this.update(json); }; Core.extend(Core.Model.JsonObject, Core.Model.Model, { /** * The number of values in the json object * @property length * @type int */ length: 0, /** * Updates the object to use the passed data set * @method update * @param json {array} jsonobject object * @public */ update: function(json) { // validation if (! isType(json,object)) {throw(JsonObject - Invalid data passed into Update);} this.parent.update.call(this, json); // private variables var data = {}, that = this, n = 0; var fx = function(key, o) { var ckey = capitalize(key); data[key] = Core.Model.XJson(o); that[(isType(o,boolean) && -1 !== key.indexOf(is))? key:get+ ckey] = function() {return data[key];}; that[set+ ckey] = function(o) { if ($type(o) !== $type(data[key])) {throw(JSONObject - invalid object passed into setter for:+ key);} data[key] = o; }; }; // iterate through the JSON object keys for (var key in json) { fx(key, json[key]); n += 1; }; // update public variables this.length = n; } }); /** * The JsonArray class manages … * @namespace Core.Model * @class JsonArray * @dependencies library */ Core.Model.JsonArray = function(json) { this.update(json); }; Core.extend(Core.Model.JsonArray, Core.Model.Model, { /** * Boolean used to inform thegetmethod to clean the cache * @property clean * @type boolean */ clean: false, /** * The number of values in the json array * @property length * @type int */ length: 0, /** * Execute functionfnon all elements in collection * @method batch * @param fn {function} the function to execute * @public */ batch: function(fn) { Core.batch(this.data, function(o, i, scope) { fn(scope.get(i), i); }, this); }, /** * Retrieve the element atifrom the collection; lazy definition to allow for converting objects on demand * @method get * @param i {int} index in the data * @public */ get: function(i) { var that = this, data = []; this.get = function(i) { // commented because this is very strict and dont always want to use, sometimes returning undefined is ok //if (! that.data[i]) {throw(JsonArray - Invalid index passed into Get:+ i);} // purges cached data on an update if (that.clean) { data = []; that.clean = false; } if (! data[i] && that.data[i]) { data[i] = Core.Model.XJson(that.data[i]); } return data[i]; }; return this.get(i); }, /** * Inserts another value into the data structure * @method push * @param o {array} new row of data * @public */ push: function(o) { if (! o) {throw(JsonArray - Invalid Object passed into Push);} this.data.push(o); this.length = this.data.length; }, /** * Updates the object to use the passed data set * @method update * @param json {array} jsonarray object * @public */ update: function(json) { // validation if (! isType(json,array)) {throw(JSONArray - Invalid JSON Array Object passed into Update);} this.parent.update.call(this, json); this.clean = true; // update public variables this.length = json.length; } }); /** * The XJsonObject class manages … * @namespace Core.Model * @class XJsonObject * @dependencies library */ Core.Model.XJsonObject = function(scheme, json) { if (! isType(scheme,array)) {throw(XJsonObject - Invalid scheme passed into Constructor);} this.scheme = scheme; this.update(json); }; Core.extend(Core.Model.XJsonObject, Core.Model.Model, { /** * The number of values in the xjson object * @property length * @type int */ length: 0, /** * The object schema * @property scheme * @type array */ scheme: [], /** * Updates the object to use the passed data set * @method update * @param json {object} XJsonObject object * @public */ update: function(json) { // validation if (! isType(json,array)) {throw(XJsonObject - Invalid data passed into Update);} if (json.length !== this.scheme.length) {throw(XJsonObject - Invalid data (does not match scheme) passed into Update);} this.parent.update.call(this, json); // private variables var data = this.data, that = this; // update public variables this.length = data.length; Core.batch(this.scheme, function(key, i, json) { var o = json[i], ckey = capitalize(key); data[i] = Core.Model.XJson(o); that[(isType(o,boolean) && -1 !== key.indexOf(is))? key:get+ ckey] = function() {return data[i];}; that[set+ ckey] = function(o) { if ($type(o) !== $type(data[key])) {throw(XJSONObject - invalid object passed into setter for:+ key);} data[i] = o; }; }, data); } }); /** * The XJsonArray class manages … * @namespace Core.Model * @class XJsonArray * @dependencies library */ Core.Model.XJsonArray = function(json) { this.update(json); }; Core.extend(Core.Model.XJsonArray, Core.Model.Model, { /** * Boolean used to inform thegetmethod to clean the cache * @property clean * @type boolean */ clean: false, /** * The number of values in the xjson array * @property length * @type int */ length: 0, /** * The object schema * @property scheme * @type array */ scheme: [], /** * Execute functionfnon all elements in collection * @method batch * @param fn {function} the function to execute * @public */ batch: function(fn) { Core.batch(this.data, function(o, i, scope) { fn(scope.get(i), i); }, this); }, /** * Retrieve the element atifrom the collection; lazy definition to allow for converting objects on demand * @method get * @param i {int} index in the data * @public */ get: function(i) { var that = this, data = []; // internally redeclaring to scope the data structure, which will contain already converted objects this.get = function(i) { // commented because this is very strict and dont always want to use, sometimes returning undefined is ok //if (! that.data[i]) {throw(XJsonArray - Invalid index passed into Get:+ i);} // purges cached data on an update if (that.clean) { data = []; that.clean = false; } if (! data[i]) { var o = that.data[i]; // if array, then it is an XJsonObject if (isType(o,array)) { data[i] = new Core.Model.XJsonObject(that.scheme, o); } // otherwise, use generic method else { data[i] = Core.Model.XJson(o); } } return data[i]; }; return this.get(i); }, /** * Inserts another value into the data structure * @method push * @param o {array} new row of data * @public */ push: function(o) { if (! (isType(o,array) && o.length === this.scheme.length)) {throw(XJsonArray - Invalid data passed into Push);} this.data.push(o); this.length = this.data.length; }, /** * Updates the object to use the passed data set * @method update * @param json {object} xjsonarray object * @public */ update: function(json) { // validation if (! (json && isType(json,object) && isType(json.scheme,array) && isType(json.set,array))) {throw(XJsonArray - Invalid data passed into Update);} this.parent.update.call(this, json.set); this.clean = true; // update public variables this.length = json.length; this.scheme = json.scheme; } }); /** * The XJson class manages … * @namespace Core.Model * @class XJson * @dependencies library */ Core.Model.XJson = function(o) { if (! o) { return null; } else if (isType(o,array) && (isType(o[0],array) || ! o.length)) { return new Core.Model.JsonArray(o); } else if (isType(o,object) && ! isType(o,array)) { return (o.scheme)? new Core.Model.XJsonArray(o): new Core.Model.JsonObject(o); } else { return o; } };
This is a lot of code to discuss, which I do not have time for today (Tuesdays article will have a detailed explanation). I have introduced a String manipulation method
capitalize, which converts strings like
mattsnider to
Mattsnider&rsquot;. This way all getter and setter methods have the appropriate capitalization. This method is from a small package of string functions, which we will discuss after these JSON objects. For now, let me know your thoughts about these objects and take a look at the test page.