app/assets/javascripts/kojac.js in kojac-0.9.1 vs app/assets/javascripts/kojac.js in kojac-0.11.0

- old
+ new

@@ -157,20 +157,85 @@ return aKeyValues; // assume already [key1, value, key2, value] } else if (_.isObject(aKeyValues)) { return _.flatten(_.pairs(aKeyValues),true); // this style : {key1: value, key2: value} } else return null; // unrecognised input - } + }, - //public static function getTrailingId(aKey: String): int { - // if (!aKey) - // return 0; - // var parts: Array = aKey.split('__') - // if (!parts.length) - // return 0; - // return StringUtils.toInt(parts[parts.length-1]) - //} + // pass a copy aPropListFn aCopyFn when you have a complex object eg. ember class. It will not be passed on to recursive calls + toJsono: function(aValue,aOptions,aPropListFn,aCopyFn) { + if (_.isObjectStrict(aValue)) { + if (!aPropListFn && !aCopyFn && ("toJsono" in aValue)) + aValue = aValue.toJsono(aOptions || {}); + else { + var aDest = {}; + aOptions = _.clone(aOptions); + var aProperties = aPropListFn ? aPropListFn(aValue) : aValue; // may return an array of properties, or an object to use the keys from + var aInclude = (aOptions && _.removeKey(aOptions,'include')); // must be an array + if (_.isString(aInclude)) + aInclude = aInclude.split(','); + if (aInclude && aInclude.length) { + if (_.isArray(aProperties)) //ensure aProperties is an array to add includes + aProperties = _.clone(aProperties); + else + aProperties = _.keys(aProperties); + for (var i=0;i<aInclude.length;i++) + aProperties.push(aInclude[i]); + } + var aExclude = (aOptions && _.removeKey(aOptions,'exclude')); // must be an array + if (_.isString(aExclude)) + aExclude = aExclude.split(','); + var p; + var v; + if (_.isArray(aProperties)) { + for (var i=0;i<aProperties.length;i++) { + p = aProperties[i]; + if (aExclude && (aExclude.indexOf(p)>=0)) + continue; + if (aCopyFn) + aCopyFn(aDest,aValue,p,aOptions); + else { + aDest[p] = Kojac.Utils.toJsono(aValue[p],aOptions); + } + } + } else { // properties is an object to use keys from + for (p in aProperties) { + if (aExclude && (aExclude.indexOf(p)>=0)) + continue; + if (aCopyFn) + aCopyFn(aDest,aValue,p,aOptions); + else { + aDest[p] = Kojac.Utils.toJsono(aValue[p],aOptions); + } + } + } + aValue = aDest; + } + } else if (_.isArray(aValue)) { + var result = []; + for (var i=0; i<aValue.length; i++) + result.push(Kojac.Utils.toJsono(aValue[i],aOptions)); + aValue = result; + } else if (_.isDate(aValue)) { + aValue = Kojac.interpretValueAsType(aValue,String); + } + return aValue; + }, + + // returns an id above the normal 32 bit range of rails but within the range of Javascript + createId: function () { + return _.randomIntRange(4294967296,4503599627370496); // 2**32 to 2**52 see http://stackoverflow.com/questions/9389315/cross-browser-javascript-number-precision + }, + + timestamp: function() { + return new Date().getTime(); + }, + + resolvedPromise: function() { + var d = jQuery.Deferred(); + return d.resolve.apply(d,arguments); + } }; /* * Function used to determine the data type class of the given value * @param {*} aValue @@ -198,10 +263,13 @@ result = Array; break; case 'object': result = Object; break; + case 'date': + result = Date; + break; case 'function': case 'class': case 'instance': case 'error': result = null; @@ -231,33 +299,21 @@ case Int: case Number: case Boolean: return aValue.toString(); break; + case Date: + return moment(aValue).toISOString(); default: case Null: return null; break; } break; case Boolean: - - switch(sourceType) { - case Null: - default: - return null; - break; - case Int: - case Number: - if (isNaN(aValue)) - return null; - else - return !!aValue; - break; - } - + return _.toBoolean(aValue,null); break; case Number: switch(sourceType) { @@ -297,10 +353,24 @@ return Math.round(Number(aValue)); break; } break; + case Date: + switch(sourceType) { + case String: + return moment.utc(aValue).toDate(); + break; + case Number: + return new Date(aValue); + break; + case Null: + default: + return null; + break; + } + break; case Object: return null; break; case Array: return null; @@ -430,11 +500,11 @@ //this.__defaults = (constructor.__defaults && _.clone(constructor.__defaults)) || {}; for (var p in prop) { if (['__defaults','__attributes'].indexOf(p)>=0) continue; var propValue = prop[p]; - if (_.isArray(propValue) && propValue.length===2 && Kojac.FieldTypes.indexOf(propValue[0])>=0) { // in form property: [Type, Default Value] + if (_.isArray(propValue) && (propValue.length===2) && (Kojac.FieldTypes.indexOf(propValue[0])>=0)) { // in form property: [Type, Default Value] this.__attributes[p] = propValue[0]; prop[p] = propValue[1]; } else if (Kojac.FieldTypes.indexOf(propValue) >= 0) { // field type prop[p] = null; this.__attributes[p] = propValue; @@ -657,11 +727,11 @@ Kojac.Operation = Kojac.Object.extend({ request: this, verb: null, key: null, value: undefined, - results: {}, + results: null, result_key: null, result: undefined, error: null, // set with some truthy error if this operation fails performed: false, fromCache: null, // null means not performed, true means got from cache, false means got from server. !!! Should split this into performed and fromCache @@ -680,10 +750,12 @@ result = undefined; else result = results[response_key]; results = _.omit(results,response_key); // results now excludes primary result + if (!this.results) + this.results = {}; _.extend(this.results,results); // store other results this.result_key = final_result_key; this.results[final_result_key] = result; // store primary result } } @@ -698,12 +770,12 @@ kojac: null, options: {}, ops: [], handlers: null, op: null, - result: undefined, - results: {}, + //result: undefined, + //results: null, error: null, // set with some truthy value if this whole request or any operation fails (will contain first error if multiple) newOperation: function() { var obj = new Kojac.Operation({request: this}); if (this.ops.length===0) this.op = obj; @@ -718,22 +790,22 @@ // {key: value} or [{key1: value},{key2: value}] or {key1: value, key2: value} // Can give existing keys with id, and will create a clone in database with a new id create: function(aKeyValues,aOptions) { - var result_key = aOptions && _.removeKey(aOptions,'result_key'); - var params = aOptions && _.removeKey(aOptions,'params'); // extract specific params - var options = aOptions ? _.extend({cacheResults: true},aOptions) : {}; // extract known options + var result_key = (aOptions && _.removeKey(aOptions,'result_key')); + var params = (aOptions && _.removeKey(aOptions,'params')); // extract specific params + var options = _.extend({cacheResults: true, manufacture: true},aOptions || {}); var kvArray = Kojac.Utils.toKeyValueArray(aKeyValues); for (var i=0;i<kvArray.length-1;i+=2) { var k = kvArray[i]; var v = kvArray[i+1]; var op = this.newOperation(); op.verb = 'CREATE'; op.options = _.clone(options); - op.params = params && _.clone(params); + op.params = (params && _.clone(params)); var parts = keySplit(k); if (parts.length >= 3) op.key = k; else op.key = keyResource(k); @@ -746,18 +818,18 @@ // !!! if aKeys is String, split on ',' into an array // known options will be moved from aOptions to op.options; remaining keys will be put into params read: function(aKeys,aOptions) { var keys = Kojac.Utils.interpretKeys(aKeys); - var result_key = aOptions && _.removeKey(aOptions,'result_key'); // extract result_key - var params = aOptions && _.removeKey(aOptions,'params'); // extract specific params - var options = aOptions ? _.extend({cacheResults: true},aOptions) : {}; // extract known options + var result_key = (aOptions && _.removeKey(aOptions,'result_key')); // extract result_key + var params = (aOptions && _.removeKey(aOptions,'params')); // extract specific params + var options = _.extend({cacheResults: true, manufacture: true},aOptions || {}); var me = this; jQuery.each(keys,function(i,k) { var op = me.newOperation(); op.options = _.clone(options); - op.params = params && _.clone(params); + op.params = (params && _.clone(params)); op.verb = 'READ'; op.key = k; if (i===0) op.result_key = result_key || k; else @@ -770,22 +842,22 @@ aOptions = _.extend({},aOptions,{preferCache: true}); return this.read(aKeys,aOptions); }, update: function(aKeyValues,aOptions) { - var result_key = aOptions && _.removeKey(aOptions,'result_key'); - var options = aOptions ? _.extend({cacheResults: true},aOptions) : {}; // extract known options - var params = aOptions && _.removeKey(aOptions,'params'); // extract specific params + var result_key = (aOptions && _.removeKey(aOptions,'result_key')); + var options = _.extend({cacheResults: true, manufacture: true},aOptions || {}); + var params = (aOptions && _.removeKey(aOptions,'params')); // extract specific params var first=true; var kvArray = Kojac.Utils.toKeyValueArray(aKeyValues); for (var i=0;i<kvArray.length-1;i+=2) { var k = kvArray[i]; var v = kvArray[i+1]; var op = this.newOperation(); op.verb = 'UPDATE'; op.options = _.clone(options); - op.params = params && _.clone(params); + op.params = (params && _.clone(params)); op.key = k; if (first) { op.result_key = result_key || k; first = false; } else @@ -795,18 +867,18 @@ return this; }, destroy: function(aKeys,aOptions) { var keys = Kojac.Utils.interpretKeys(aKeys); - var result_key = aOptions && _.removeKey(aOptions,'result_key'); - var options = aOptions ? _.extend({cacheResults: true},aOptions) : {}; // extract known options - var params = aOptions && _.removeKey(aOptions,'params'); // extract specific params + var result_key = (aOptions && _.removeKey(aOptions,'result_key')); + var options = _.extend({cacheResults: true},aOptions || {}); + var params = (aOptions && _.removeKey(aOptions,'params')); // extract specific params var me = this; jQuery.each(keys,function(i,k) { var op = me.newOperation(); op.options = _.clone(options); - op.params = params && _.clone(params); + op.params = (params && _.clone(params)); op.verb = 'DESTROY'; op.key = k; if (i===0) op.result_key = result_key || k; else @@ -817,14 +889,14 @@ execute: function(aKey,aValue,aOptions) { var op = this.newOperation(); op.verb = 'EXECUTE'; - var params = aOptions && _.removeKey(aOptions,'params'); // extract specific params - op.result_key = aOptions && _.removeKey(aOptions,'result_key') || aKey; - op.options = aOptions ? _.extend({cacheResults: false},aOptions) : {}; // extract known options - op.params = params && _.clone(params); + var params = (aOptions && _.removeKey(aOptions,'params')); // extract specific params + op.result_key = (aOptions && _.removeKey(aOptions,'result_key')) || aKey; + op.options = _.extend({cacheResults: false, manufacture: false},aOptions || {}); + op.params = (params && _.clone(params)); op.key = aKey; op.value = aValue; return this; }, @@ -847,57 +919,89 @@ newRequest: function() { return new Kojac.Request({kojac: this}); }, - cacheResults: function(aRequest) { +// var v; +// for (var i=0;i<aRequest.ops.length;i++) { +// var op = aRequest.ops[i]; +// if (op.error) +// break; +// if (op.options.cacheResults===false) +// continue; +// for (p in op.results) { +// if (p==op.result_key) +// continue; +// v = op.results[p]; +// if (v===undefined) +// delete this.cache[p]; +// else +// this.cache[p] = op.results[p]; +// } +// v = op.results[op.result_key]; +// if (v===undefined) { +// delete this.cache[op.result_key]; +// } else { +// this.cache[op.result_key] = v; +// } +// console.log('end of loop'); +// } + + handleResults: function(aRequest) { if (this.cache.beginPropertyChanges) this.cache.beginPropertyChanges(); - for (var i=0;i<aRequest.ops.length;i++) { - var op = aRequest.ops[i]; - if (op.error) - break; - if (op.options.cacheResults===false) - continue; - for (p in op.results) { - if (p==op.result_key) - continue; - if (op.results[p]===undefined) - delete this.cache[p]; - else - this.cache[p] = op.results[p]; + + var updatedObjects = []; + + try { + for (var i=0;i<aRequest.ops.length;i++) { + var op = aRequest.ops[i]; + if (op.error) + break; + + for (var key in op.results) { + var value = op.results[key]; + if ((op.options.atomise!==false) && _.isObjectStrict(value)) { + var existing = this.cache.retrieve(key); + if (_.isObjectStrict(existing)) { + if (existing.beginPropertyChanges) { + existing.beginPropertyChanges(); + updatedObjects.push(existing); + } + if (existing.setProperties) + existing.setProperties(value); + else + _.copyProperties(existing,value); + value = existing; + } else { + if ((op.options.manufacture!==false) && (this.objectFactory)) + value = this.objectFactory.manufacture(value,key); + } + } + op.results[key] = value; + if (op.options.cacheResults!==false) + this.cache.store(key,value); + } } - if (op.results[op.result_key]===undefined) - delete this.cache[op.result_key]; - else - this.cache[op.result_key] = op.results[op.result_key]; + } finally { + for (var i=0;i<updatedObjects.length;i++) + updatedObjects[i].endPropertyChanges(); } if (this.cache.endPropertyChanges) this.cache.endPropertyChanges(); }, - cacheHasKeys: function(aKeysArray) { - var me = this; - return _.all(aKeysArray,function(k){ - return k in me.cache; - }) - }, - - cacheValues: function(aKeysArray) { - var me = this; - return _.map(aKeysArray,function(k){ - return me.cache[k]; - }) - }, - - finaliseRequest: function(aRequest) { + finaliseResponse: function(aRequest) { // set convenience properties var results = {}; - for (var i=0;i<aRequest.ops.length;i++) { + if (!aRequest.error) for (var i=0;i<aRequest.ops.length;i++) { var op = aRequest.ops[i]; - if (op.error && !aRequest.error) - aRequest.error = op.error; + if (op.error) { + if (!aRequest.error) + aRequest.error = op.error; + break; + } _.extend(results,op.results); op.result = !op.error && op.results && (op.result_key || op.key) ? op.results[op.result_key || op.key] : null; if (i===0) { aRequest.op = op; } @@ -915,41 +1019,46 @@ } else { aRequest.kojac.dependentKeys[op.key] = dep_keys } } } - aRequest.results = results; - aRequest.result = aRequest.op && aRequest.op.result; + if (aRequest.error) { + _.removeKey(aRequest,'results'); + _.removeKey(aRequest,'result'); + } else { + aRequest.results = results; + aRequest.result = (aRequest.op && aRequest.op.result); + } }, performRequest: function(aRequest) { for (var i=0;i<aRequest.ops.length;i++) { - var op = aRequest.ops[i]; + var op = aRequest.ops[i] + op.results = {}; var k = (op.result_key && (op.result_key !== op.key)) ? op.result_key : op.key; - if (op.verb=='READ' && op.options.preferCache && (k in aRequest.kojac.cache)) { // resolve from cache - op.results[k] = aRequest.kojac.cache[k]; + var cacheValue = aRequest.kojac.cache.retrieve(k); + if ((op.verb=='READ') && op.options.preferCache && (cacheValue!==undefined)) { // resolve from cache + op.results[k] = cacheValue; var dep_keys = aRequest.kojac.dependentKeys[op.key]; if (dep_keys) { for (var i=0;i<dep_keys.length;i++) { var dk = dep_keys[i]; // what if not in cache? perhaps dump siblings in dependentKeys and index key to cause full refresh? or refuse to remove from cache if in dependentKeys - op.results[dk] = aRequest.kojac.cache[dk]; + op.results[dk] = aRequest.kojac.cache.retrieve(dk); } } op.result_key = k; op.fromCache = true; op.performed = true; } } - aRequest.handlers.add(this.remoteProvider.handleAjaxRequest,null,this.remoteProvider); - if (this.objectFactory && this.objectFactory.transformResultsToValueObjects) - aRequest.handlers.add(this.objectFactory.transformResultsToValueObjects,null,this.objectFactory); - if (this.cache.cacheResults) - aRequest.handlers.add(this.cache.cacheResults,null,this.cache); - else - aRequest.handlers.add(this.cacheResults,null,this); - aRequest.handlers.run(aRequest).then(this.finaliseRequest); + aRequest.handlers.add(this.remoteProvider.handleRequest,null,this.remoteProvider); + + //if (this.objectFactory) + aRequest.handlers.add(this.handleResults,null,this); + + aRequest.handlers.run(aRequest).always(this.finaliseResponse); return aRequest; }, // BEGIN User Functions @@ -1005,10 +1114,25 @@ return this.execute(aKey,aValue,aOptions).request(); } // END Convenience Functions }); +Kojac.Cache = Kojac.Object.extend({ + store: function(k,v) { + if (v===undefined) { + delete this[k]; + return v; + } else { + return (this[k] = v); + } + }, + retrieve: function(k) { + return this[k]; + } +}); + + /** * A default RemoteProvider implementation. Your own implementation, or a subclass of this may be used instead. * @class Kojac.RemoteProvider * @extends Kojac.Object */ @@ -1016,10 +1140,11 @@ useMockFileValues: false, mockFilePath: null, mockReadOperationHandler: null, serverPath: null, + timeout: 10000, mockWriteOperationHandler: null,//function(aOp) { // Ember.Logger.log(JSON.stringify(CanUtils.copyProperties({},aOp,null,['request']))); // }, @@ -1030,27 +1155,25 @@ var jsonOp = { verb: op.verb, key: op.key }; if ((op.verb==='CREATE') || (op.verb==='UPDATE') || (op.verb==='EXECUTE')) { - if (op.value && ("toObject" in op.value)) - jsonOp.value = op.value.toObject(op.options); - else - jsonOp.value = op.value; + jsonOp.value = Kojac.Utils.toJsono(op.value,op.options); } - var options = op.options && _.omit(op.options,['cacheResults','preferCache']); + var options = (op.options && _.omit(op.options,['cacheResults','preferCache'])); if (options && !_.isEmpty(options)) jsonOp.options = options; // omit local keys jsonOp.params = op.params; result.push(jsonOp); } return result }, - handleAjaxRequest: function(aRequest) { + handleRequest: function(aRequest) { var result; var op; + var me = this; for (var i=0;i<aRequest.ops.length;i++) { op = aRequest.ops[i]; if (op.performed) continue; if (op.verb==='READ' || op.verb==='EXECUTE') { @@ -1074,20 +1197,19 @@ var server_ops = _.filterByCriteria(aRequest.ops,{performed: false}); if (!server_ops.length) return; if (this.useMockFileValues) { aRequest.handlers.waitForCallNext = true; - var me = this; var getMockFile = function(aOp) { var fp = me.mockFilePath+aOp.key+'.js'; var data = null; - return jQuery.ajax({url: fp, dataType: 'json', cache: false, data: data}).done( + return jQuery.ajax({url: fp, dataType: 'json', cache: false, data: data, timeout: me.timeout}).done( function( aData ) { for (p in aData) { if (p==='results') { for (k in aData.results) { - if (k===aOp.key && (aOp.result_key!=aOp.key)) + if ((k===aOp.key) && (aOp.result_key!=aOp.key)) aOp.results[aOp.result_key] = aData.results[k]; else aOp.results[k] = aData.results[k]; } } else @@ -1117,10 +1239,11 @@ version: 'KOJAC-1.0', ops: opsJson } }; aRequest.handlers.waitForCallNext = true; + // !!! might need to include X-CSRF-Token see http://stackoverflow.com/questions/8511695/rails-render-json-session-lost?rq=1 var ajaxpars = { type: 'POST', data: JSON.stringify(dataToSend), contentType: "application/json; charset=utf-8", dataType: "json" @@ -1129,29 +1252,187 @@ // poke results into request ops using request_op_index aRequest.xhr = aXhr; for (var i=0;i<server_ops.length;i++) { var opRequest = server_ops[i]; //aRequest.ops[request_op_index[i]]; var opResult = (_.isArray(aResult.ops) && (i<aResult.ops.length) && aResult.ops[i]); - opRequest.receiveResult(opResult); opRequest.fromCache = false; opRequest.performed = true; + if (opResult.error) { + opRequest.error = opResult.error; + aRequest.handlers.handleError(opResult.error); + break; + } else { + opRequest.receiveResult(opResult); + } } aRequest.handlers.callNext(); }).fail(function(aXhr,aStatus,aError){ + aRequest.error = me.interpretXhrError(aXhr); + //_.removeKey(aRequest,'results'); for (var i=0;i<server_ops.length;i++) { var opRequest = server_ops[i]; //aRequest.ops[request_op_index[i]]; opRequest.fromCache = false; opRequest.performed = true; + //if (opRequest.error) + // _.removeKey(opRequest,'results'); } - aRequest.error = aXhr; - aRequest.handlers.handleError(aXhr); + aRequest.handlers.handleError(aRequest.error); aRequest.handlers.callNext(); }); } + }, + + interpretXhrError: function(aXhr) { + var http_code = null; + var kind = null; + var message = null; + var debug_message = null; + var response = null; + var headers = null; + if (http_code = (aXhr && aXhr.status)) { + kind = (aXhr.statusText && aXhr.statusText.replace(' ','')); + message = debug_message = aXhr.statusText; + headers = aXhr.getAllResponseHeaders(); + response = aXhr.responseText; + } else { + http_code = null; + kind = "NetworkError"; + message = "Failed to connect. Please check network or try again"; + debug_message = "Network connection failed"; + } + return { + format: 'KojacError', + http_code: http_code, // a valid HTTP status code, or null + kind: kind, // CamelCase text name of error, for conditional code handling + message: message, // an explanation for normal humans + debug_message: debug_message, // an explanation for developers + xhr: aXhr, // the original XHR object from jQuery + headers: headers, // all response headers + response: response // the response body + } } }); + +Kojac.LocalStorageRemoteProvider = Kojac.Object.extend({ + operationsToJson: function(aOps) { + var result = []; + for (var i=0;i<aOps.length;i++) { + var op = aOps[i]; + var jsonOp = { + verb: op.verb, + key: op.key + }; + if ((op.verb==='CREATE') || (op.verb==='UPDATE') || (op.verb==='EXECUTE')) { + jsonOp.value = Kojac.Utils.toJsono(op.value,op.options); + } + var options = (op.options && _.omit(op.options,['cacheResults','preferCache'])); + if (options && !_.isEmpty(options)) + jsonOp.options = options; // omit local keys + jsonOp.params = op.params; + result.push(jsonOp); + } + return result + }, + + handleRequest: function(aRequest) { + var aRequestOp; + if (!aRequest.ops.length) + return; + var ops = this.operationsToJson(aRequest.ops); + var op_output; + var v,op,id,key,value,parts,results,result_key; + for (var i=0;i<ops.length;i++) { + op = ops[i]; + aRequestOp = aRequest.ops[i]; + if (op.verb=='CREATE') { + id = Kojac.Utils.createId(); + key = keyJoin(op.key,id); + result_key = (op.result_key || key); + value = _.clone(op.value,true,true); + value.id = id; + + $.jStorage.set(key,value); + results = {}; + results[result_key] = value; + op_output = { + key: op.key, + verb: op.verb, + result_key: result_key, + results: results + }; + } else if (op.verb=='READ') { + result_key = (op.result_key || op.key); + results = {}; + parts = keySplit(op.key); + if (parts[1]) { // item + value = $.jStorage.get(op.key,Boolean); + if (value===Boolean) + value = undefined; + results[result_key] = value; + } else { // collection + var keys = $.jStorage.index(); + var ids = []; + _.each(keys,function(k){ + parts = keySplit(k); + id = parts[1]; + if (parts[0]!=op.key || !id) + return; + ids.push(id); + v = $.jStorage.get(k,Boolean); + if (value===Boolean) + value = undefined; + results[k] = v; + }); + results[result_key] = ids; + } + op_output = { + key: op.key, + verb: op.verb, + result_key: result_key, + results: results + }; + } else if (op.verb=='UPDATE') { + value = $.jStorage.get(op.key,Boolean); + if (value===Boolean) + value = undefined; + result_key = (op.result_key || op.key); + if (_.isObjectStrict(value)) + _.extend(value,op.value); + else + value = op.value; + $.jStorage.set(op.key,value); + results = {}; + results[result_key] = value; + op_output = { + key: op.key, + verb: op.verb, + result_key: result_key, + results: results + }; + } else if (op.verb=='DESTROY') { + $.jStorage.deleteKey(op.key); + result_key = (op.result_key || op.key); + results = {}; + //results[result_key] = undefined; + op_output = { + key: op.key, + verb: op.verb, + result_key: result_key, + results: results + }; + } else { + throw "verb not implemented"; + } + aRequestOp.receiveResult(op_output); + aRequestOp.fromCache = false; + aRequestOp.performed = true; + } + } +}); + + /** * A default ObjectFactory implementation. Your own implementation, or a subclass of this may be used instead. * @class Kojac.ObjectFactory * @extends Kojac.Object */ @@ -1171,11 +1452,11 @@ classFromKey: function(aKey) { var pair; var re; var newClass; - for (var i = 0; i < this.matchers.length; i++) { + if (this.matchers) for (var i = 0; i < this.matchers.length; i++) { pair = this.matchers[i]; re = pair[0]; if (!re.test(aKey)) continue; newClass = pair[1]; @@ -1207,24 +1488,11 @@ } } else { var newClass = this.classFromKey(aKey); result = me.createInstance(newClass,aObject); } + console.log('END manufacture'); return result; - }, - - transformResultsToValueObjects: function(aRequest) { - for (var i=0;i<aRequest.ops.length;i++) { - var op = aRequest.ops[i]; - if (op.error) - break; - for (var k in op.results) { - var v = op.results[k]; - if (!jQuery.isPlainObject(v)) - continue; - op.results[k] = this.manufacture(v,k); - } - } } });